Exists句

■Exsists句は、INの様に

 ・条件に一致するもの

 ・条件に一致しないもの

 といったデータを高速に抽出することができる。

 

ex1)

f:id:akCs:20210326103318p:plain

①上記データから、全教科50点以上のStudent‗idを抽出する

SELECT DISTINCT T1.student_id FROM TestScore AS T1

WHERE NOT EXISTS(

    SELECT * FROM TestScore T2 WHERE

    T1.student_id = T2.student_id AND T2.score <=50

)

(*)50点以下があるstudent_idと一致しないデータと考える。

 サブクエリ(T2)のSelect *部分は、*でも個別の列名でも結果は同じ

 逆にscore >50としてしまうと、1教科でも50点以上があるidとなる

 

②上記データから、国語90点以上を取ったIDを取得する

SELECT DISTINCT T1.student_id FROM TestScore AS T1

WHERE EXISTS(

    SELECT * FROM TestScore T2 WHERE

    T1.student_id = T2.student_id AND

 T2.subject = '国語' AND

 T2.score >= 90)

)

(*)国語が90点以上であるstudent_idと一致するデータと考える

 

③上記データから、国語50点以上、算数80点以上を取ったIDを取得する

SELECT * FROM TestScore AS T1

WHERE NOT EXISTS(

  SELECT * FROM TestScore AS T2 WHERE T1.student_id = T2.student_id AND

  1 =

   case when subject ='国語' and score < 50 Then 1

      when subject ='算数' and score < 80 then 1 else 0

   end

)

(*)算数80点未満、または国語50点未満を取っているstudent_idと一致しないデータ。

 

ex2)

 f:id:akCs:20210326120142p:plain

 meetingの各回毎の出席者表(全員が少なくとも1回は何れかの回に参加している前提)

④上記表から、meeting各回の欠席者を抽出する。

SELECT DISTINCT m1.meeting,m2.person FROM meetings m1 /* ←直積 */

CROSS JOIN meetings m2
WHERE NOT EXISTS(
 SELECT * FROM meetings m3
 WHERE m1.meeting = m3.meeting AND m2.person = m3.person
)

 

(*)meeting各回とpersonの全組み合わせ(全員が全ての回に出席した場合のデータ=直積)

から、実際の参加状況と一致するものを除くと考える