どちらのクエリも
SQL
1-- (Q1)
2select *
3from students s1;
という単純な形でこれは以下の結果になります(A)。
text
1 student_id | dpt | sbmt_date
2------------+----------+------------
3 100 | 理学部 | 2018-10-10
4 101 | 理学部 | 2018-09-22
5 102 | 文学部 |
6 103 | 文学部 | 2018-09-10
7 200 | 文学部 | 2018-09-22
8 201 | 工学部 |
9 202 | 経済学部 | 2018-09-25
これにサブクエリによる条件が付き
SQL
1-- (Q2)
2...
3WHERE not exists(
4--サブクエリ
5...
6);
のような形になっています。条件が満たされていれば上の各行は出力されるわけです。なので各行を1行ずつ見てそれぞれのクエリで条件が満たされるかどうか見ていきます。
正しい方のクエリの場合
サブクエリが
SQL
1-- (Q3)
2select *
3from students s2
4WHERE s1.dpt = s2.dpt
5and s2.sbmt_date is null
のようになっています。では上の(A)の結果の1行目が条件を満たすか見ていきます。この行はdpt
が'理学部'
なので、サブクエリは以下の形と等価になります。
SQL
1-- (Q4)
2select *
3from students s2
4WHERE '理学部' = s2.dpt
5and s2.sbmt_date is null
このクエリの結果は
text
1 student_id | dpt | sbmt_date
2------------+-----+-----------
3(0 rows)
になります。not exsits
が条件なので、この行は見事に条件を満たしていることが分かります。同様に2行目はdpt
が'理学部'
なので、上のクエリ(Q4)と同じになり、同じく条件を満たします。
次の3行目はdpt
が'文学部'
なので、サブクエリは以下の形と等価になります。
SQL
1-- (Q5)
2select *
3from students s2
4WHERE '文学部' = s2.dpt
5and s2.sbmt_date is null
このクエリの結果は
text
1 student_id | dpt | sbmt_date
2------------+--------+-----------
3 102 | 文学部 |
になります。not exsits
が条件なので、この行は条件を満たしていないことが分かります。同様に4~5行目はdpt
が'文学部'
なので、上のクエリ(Q5)と同じになり、同じく条件を満たしていません。
次の6行目はdpt
が'工学部'
なので、サブクエリは以下の形と等価になります。
SQL
1-- (Q6)
2select *
3from students s2
4WHERE '工学部' = s2.dpt
5and s2.sbmt_date is null
このクエリの結果は
text
1 student_id | dpt | sbmt_date
2------------+--------+-----------
3 201 | 工学部 |
になります。not exsits
が条件なので、この行は条件を満たしていないことが分かります。
次の7行目はdpt
が'経済学部'
なので、サブクエリは以下の形と等価になります。
SQL
1-- (Q7)
2select *
3from students s2
4WHERE '経済学部' = s2.dpt
5and s2.sbmt_date is null
このクエリの結果は
text
1 student_id | dpt | sbmt_date
2------------+-----+-----------
3(0 rows)
になります。not exsits
が条件なので、この行は条件を満たしていることが分かります。
結果、条件を満たす全行は
text
1 student_id | dpt | sbmt_date
2------------+----------+------------
3 100 | 理学部 | 2018-10-10
4 101 | 理学部 | 2018-09-22
5 202 | 経済学部 | 2018-09-25
となります。
間違っている方のクエリの場合
サブクエリが
SQL
1-- (Q8)
2select *
3from students s2
4WHERE s1.dpt = s2.dpt
5and s1.sbmt_date is null
のようになっています。では上の(A)の結果の1行目が条件を満たすか見ていきます。この行はdpt
が'理学部'
でsbmt_date
が'2018-10-10'
なので、サブクエリは以下の形と等価になります。
SQL
1-- (Q9)
2select *
3from students s2
4WHERE '理学部' = s2.dpt
5and '2018-10-10' is null
このクエリの結果は
text
1 student_id | dpt | sbmt_date
2------------+-----+-----------
3(0 rows)
になります。not exsits
が条件なので、この行は見事に条件を満たしていることが分かります。ただ、そもそも'2018-10-10' is null
の結果は明らかに偽なので、テーブルにアクセスすることなく結果が空であることが分かります。
2行目はdpt
が'理学部'
でsbmt_date
が'2018-09-22'
なので、サブクエリは以下の形と等価になります。
SQL
1-- (Q10)
2select *
3from students s2
4WHERE '理学部' = s2.dpt
5and '2018-09-22' is null
このクエリの結果は
text
1 student_id | dpt | sbmt_date
2------------+-----+-----------
3(0 rows)
になります。not exsits
が条件なので、この行は見事に条件を満たしていることが分かります。1行目と同様ですね。
後はもう分かるとおり、s1
のsbmt_date
がnull
ならs2
にアクセスすることなくその行は出力されず、null
以外ならs2
のdpt
が必ず結合可能なため、出力されます。結果は
text
1 student_id | dpt | sbmt_date
2------------+----------+------------
3 100 | 理学部 | 2018-10-10
4 101 | 理学部 | 2018-09-22
5 103 | 文学部 | 2018-09-10
6 200 | 文学部 | 2018-09-22
7 202 | 経済学部 | 2018-09-25
のとおりです。つまりこの結果は、dpt
にnull
が入らないなら以下と同じことになります。
SQL
1select *
2from students
3WHERE sbmt_date is not null;
結論
サブクエリ側の表を対象としてsbmt_date
のnull
を判定しないとサブクエリにする意味がない
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/11/09 01:09
2021/11/09 01:25 編集
退会済みユーザー
2021/11/09 03:32
2021/11/09 04:31
退会済みユーザー
2021/11/09 04:47
2021/11/09 05:10