質問: 練習問題が解けないので教えてください。 下記のSQLで売上トップ5の商品を除く、 社員別の売上データを出したいのですが、 SQLを実行しても何も出てきません・・・ not existsの使い方が間違っているのでしょうか? ``` select FORMAT(受注.受注日,'yyyy') as 受注年, 社員.社員コード,社員.氏名,社員.在籍支社,社員.部署名, sum(受注明細.単価*受注明細.数量) as 売上 from (受注 inner join 受注明細 on 受注.受注コード=受注明細.受注コード) inner join 社員 on 社員.社員コード=受注.社員コード inner join 商品 on 商品.商品コード=受注明細.商品コード where not exists (select TOP 5 商品.商品名/*,sum(受注明細.単価*受注明細.数量) as 売上*/ from (受注 inner join 受注明細 on 受注.受注コード=受注明細.受注コード) inner join 商品 on 受注明細.商品コード=商品.商品コード inner join 商品区分 on 商品.区分コード=商品区分.区分コード group by 商品.商品名 order by sum(受注明細.単価*受注明細.数量) DESC) group by FORMAT(受注.受注日,'yyyy'),社員.社員コード,社員.氏名,社員.在籍支社,社員.部署名 order by 売上 DESC ```
回答: > テーブルの定義とか提示しなきゃ、回答なんてできませんよ。 という Kosuke_Shibuyaさんのツッコミはごもっともですね... ところで、試しに「NOT EXISTS を使用したサブクエリ」の部分だけを実行してみてください。 ``` select TOP 5 商品.商品名/*,sum(受注明細.単価*受注明細.数量) as 売上*/ from (受注 inner join 受注明細 on 受注.受注コード=受注明細.受注コード) inner join 商品 on 受注明細.商品コード=商品.商品コード inner join 商品区分 on 商品.区分コード=商品区分.区分コード group by 商品.商品名 order by sum(受注明細.単価*受注明細.数量) DESC ``` 結果は**該当データなし**になりましたか? NOT EXISTS が使用されている WHERE 句が条件を満たすのは、対応するサブクエリによって返される行がない場合です。 > 売上トップ5の商品を除く というのと、**TOP5に該当するデータなし**は、明らかに違うのでは?? **TOP5に該当するデータなし**という条件が成立するのは、この部分のSQLで返される行が全く無い場合ですから... ``` select 商品.商品名/*,sum(受注明細.単価*受注明細.数量) as 売上*/ from (受注 inner join 受注明細 on 受注.受注コード=受注明細.受注コード) inner join 商品 on 受注明細.商品コード=商品.商品コード inner join 商品区分 on 商品.区分コード=商品区分.区分コード group by 商品.商品名 ``` そんな条件の成立するようなテーブルの結合方法は、そもそも変ですよね? SQLを書く際、つい頑張ってグイグイと書いてしまった後でハマり*???*となるケースがありますけれども、謎を解くカギは、SQLを部分的に(サブクエリのみを)実行して結果を試して見ることです。 ちなみに、**TOP5を除く**の書き方ですが、SQLで上位5つのレコードを表示する方法の後半の説明が参考になりませんか?