LoginSignup
0
0

More than 3 years have passed since last update.

not existsを扱う

Posted at

以下のテーブルがある。

select * from testscores;

+------------+---------+-------+
| student_id | subject | score |
+------------+---------+-------+
|        100 | 国語    |    80 |
|        100 | 理科    |    80 |
|        100 | 算数    |   100 |
|        200 | 国語    |    95 |
|        200 | 算数    |    80 |
|        300 | 国語    |    90 |
|        300 | 社会    |    55 |
|        300 | 算数    |    40 |
|        400 | 算数    |    80 |
+------------+---------+-------+

全ての教科で50点以上取っている生徒を取得する。

select
distinct student_id
from
testscores ts1
where
not exists
(
    select
    *
    from
    testscores ts2
    where
    ts1.student_id = ts2.student_id
    and ts2.score < 50
)

+------------+
| student_id |
+------------+
|        100 |
|        200 |
|        400 |
+------------+

次は算数が80点以上、国語が50点以上の生徒を取得する。

select
distinct student_id
from
testscores ts1
where
subject in('算数','国語')
and not exists
(
    select
    *
    from
    testscores ts2
    where
    ts1.student_id = ts2.student_id
    and 1 =
    case when subject = '算数' and score < 80 then 1
    when subject = '国語' and score < 50 then 1
    else 0 end
)

+------------+
| student_id |
+------------+
|        100 |
|        200 |
|        400 |
+------------+

上記のSQLでは、国語のデータが存在しないstudent_id400の生徒が取得されてしまっている。
それを除外したい場合、行数を数えるhaving句を追加すればいい。

select
student_id
from
testscores ts1
where
subject in('算数','国語')
and not exists
(
    select
    *
    from
    testscores ts2
    where
    ts1.student_id = ts2.student_id
    and 1 =
    case when subject = '算数' and score < 80 then 1
    when subject = '国語' and score < 50 then 1
    else 0 end
)
group by student_id
having count(*) = 2

+------------+
| student_id |
+------------+
|        100 |
|        200 |
+------------+

こちらを参考にさせていただきました。
達人に学ぶSQL徹底指南書 第2版 初級者で終わりたくないあなたへ

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0