相関副問合せ  ネスト

柴犬さん  
(No.1)
すべての商品を納入する商社名を調べるSQLらしいです。
not existsで複数条件のときの考えがわかりません。

納品(商品番号  商社番号  数)
商品(商社番号  商品名)
商社(商社番号  商社名)

select distinct 商社.商社名  from 商社
where not exsits 
  (select * from 商品
  where not exists 
    (select * from 納品
      where 納品.商品番号=商品.商品番号
&納品.商社番号=商社.商社番号))



例えでデータを当てはめてみたのですがさっぱりです。
商社
A01 山田社
A02 佐藤社

商品
001  いも
002  こめ
003  むぎ

納品
001  A01 2こ
003  A01 10こ
001   A02 10こ
002   A02 2こ
003   A02 3こ

としてみました。

まずは商社A01 に対して商品001-003をすべて存在チェックするので、
001いも  真
002こめ  偽
003むぎ  真
となります。

from 商品  の所はnot existsなので
001いも  真→偽
002こめ  偽→真
003むぎ  真→偽
となると思います。

①相関副問合せは一つずつチェックすると説明文に書いてありました。
001いも  の時点で判定が偽となるのでそこで処理が終了しそうなのですが、なぜ002こめ…と処理が続くのでしょうか?

②from 商社のところへはなぜ真が返るのでしょうか?
A01 に対して、商品3つを確認すると(偽、真、偽)なので偽が返るような気がするのですが…
2021.01.11 19:42
関数従属さん 
DB ブロンズマイスター
(No.2)
existsは存在チェックであり、
カッコの中のSQLの返却レコード数が0件の場合に偽、0件以外の場合は真となります。
(not existsの場合は逆となるため0件の場合に真、0件以外の場合は偽となります。)

select * from 納品
 where 納品.商品番号=商品.商品番号
   and 納品.商社番号=商社.商社番号
のSQLの部分は
A01 山田社 001いも だとレコード1件
A01 山田社 002こめ だとレコード0件
A01 山田社 003むぎ だとレコード1件
を返却する事になります。

①上記でレコード数をチェックする事になるため、001いもの次に002こめ、003むぎとチェックしていきます。

select * from 商品 where not exists の部分は
カッコの中のレコード数が0件である002こめは真であり、002こめのレコード1件が返却されます。

②select distinct 商社.商社名  from 商社 where not exsits の部分は
002こめのレコード1件が返却されているため、偽となり、A01 山田社のレコードは抽出されません。

尚、A02 佐藤社の場合は

select * from 納品
 where 納品.商品番号=商品.商品番号
   and 納品.商社番号=商社.商社番号

のSQLの部分は

A02 佐藤社 001いも だとレコード1件
A02 佐藤社 002こめ だとレコード1件
A02 佐藤社 003むぎ だとレコード1件
を返却し、select * from 商品 where not exists の部分は
カッコの中のレコード数が0件のものがないため、レコード0件が返却され
select distinct 商社.商社名  from 商社 where not exsits の部分は
レコード0件が返却されているため、真となり、A02 佐藤社のレコードが抽出されます。
2021.01.12 22:36

返信投稿用フォーム

スパム防止のためにスレッド作成日から30日経過したスレッドへの書込みはできません。

その他のスレッド


Pagetop