質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

1回答

7709閲覧

NULLが含まれるデータに対する「NOT IN」と「NOT EXISTS」の出力結果の違いについて

sysder

総合スコア25

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

1クリップ

投稿2020/02/03 14:12

編集2020/02/04 12:41

以下の本の例題で分からないところがあります。
達人に学ぶSQL徹底指南書

以下の二つのテーブルがあります。
tableA

nameagecity
a22tokyo
b19saitama
c21chiba

tableB

nameagecity
aa22tokyo
bb23tokyo
cctokyo
dd25chiba

「tableBのtokyoの人と年齢が一致しないtableAの人」を抽出するのですが、
下記のNOT INで書いたSQLだと、一行も抽出されないことは理解できました。

SQL

1select * 2 from tableA 3 where age NOT IN 4 (select age 5 from tableB 6 where city = 'tokyo');

しかし、下記のNOT EXISTSで書いたSQLは、なぜbとcが抽出されるのか理解できません。

SQL

1select * 2 from tableA A 3 where NOT EXISTS 4 (select * 5 from tableB B 6 where A.age = B.age 7 and B.city = 'tokyo');

NOT EXISTS内の評価は、
tableAのage 22とtableBのage 22 23 NULLとがイコールかどうか比較するので、
True and False and unknown = False
となって、このNOTなのでTrueとなるのでしょうか。
しかしそうなると、tableAのage 19とtableBのage 22 23 NULLとの比較も
False and False and unknown = False
となってTrueになってしまいます。

なぜ、NOT EXISTSで書いたSQLは、bとcが抽出されるのでしょうか。
ご教示の程何卒よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sazi

2020/02/03 14:48

aとbじゃなくてbとCじゃないですか?
sysder

2020/02/04 12:38

おっしゃる通りです。 修正いたしました。
guest

回答1

0

ベストアンサー

EXISTSの条件で考えると、aが抽出されます。
それがNotでの補集合ですから、bとCが抽出されます。
ドモルガンの法則の解説

投稿2020/02/03 18:11

sazi

総合スコア25138

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sysder

2020/02/04 13:10

回答ありがとうございます。 なぜNOT EXISTSだとNULLがあってもちゃんと抽出されるのでしょうか。 NOT INだと、データにNULLがあった場合に以下のような判定になって、Tureは絶対に返らないようです。 where NOT age IN (22, 23, NULL) NOT((age=22) or (age=23) or (age=NULL)) ドモルガンの法則で、 (age<>22) and (age<>23) and(age<>NULL) (age<>22) and (age<>23) and unknown falseまたはunknown しかしNOT EXISTSの場合は where NOT EXISTS (select * from tableB where falseまたはunknown) where true となってNULLがレコードにあってもbとcが抽出されるそうです。
sazi

2020/02/04 13:51 編集

そもそもNotを指定した場合の補集合については理解されましたか? それが理解できれば、後はサブクエリーがどういう値を返すかだけです
sazi

2020/02/04 13:53

Not Existsについては相関副問合せの挙動の理解が前提です
sysder

2020/02/05 14:47

>そもそもNotを指定した場合の補集合については理解されましたか? 以下で理解しました。 https://teratail.com/questions/51648 検索結果が0件の時であれば、すなわちサブクエリ内の結果がFalseであれば、外側のテーブルのレコードを残します。 >それが理解できれば、後はサブクエリーがどういう値を返すかだけです ここが分かりません。 以下、僕の理解になりますがどこが間違っているのでしょうか。 TableAのaの行とTableBを比較する場合、TableAの22とTableBの22がTrue、TableBの23がFalse、TableBのNULLがunknownになる。 この結果がANDで結ばれるので、True AND False AND unknown になる。 True AND False AND unknown = unknown になってTableAの22に対してはサブクエリはunknownを返す。 そのNOTなのでunknownはunknownのままである。 よってTableAの22のレコードが抽出されない。 >Not Existsについては相関副問合せの挙動の理解が前提です 相関副問合せは、自己結合の場合でなくてもいいのでしょうか。 今回の場合、TableAとTableBと異なるテーブルを使っているので、相関副問合せではないのかと思っていました。
sazi

2020/02/05 15:05 編集

「ableAの22とTableBの22がTrue、TableBの23がFalse、TableBのNULLがunknownになる。 この結果がANDで結ばれるので」 この「この結果がANDで結ばれるの」という理解が誤っています。 相関副問合せはそれぞれ独立した結果なのです。 私の説明より、検索すればもっと分かり易いものが見つかるでしょう
sysder

2020/02/06 13:51

>この「この結果がANDで結ばれるの」という理解が誤っています。 >相関副問合せはそれぞれ独立した結果なのです。 なるほど。ようやく理解できました。 以下のサイトも参考にしました。 atmarkit.co.jp/ait/articles/1209/14/news146.html ご丁寧にご回答いただきまして誠にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問