コマンド道場
INTERSECT難易度 ★★★☆☆

2 年続けて受注がある顧客

2025 年中にも 2026 年中にも、取消されていない受注(status が 'done')がある顧客を取り出してください。列は「顧客名」だけ、顧客名の昇順に並べてください。

この書き方が使えない製品があります そのまま使える: PostgreSQL / MySQL / MariaDB / SQLite / SQL Server / Oracle Database

未確認: IBM Db2

製品ごとの対応表(実測)を見る

  • INTERSECT は両方に共通する行だけを残します。重複は取り除かれます。
  • MySQL で使えるのは 8.0.31 以降です。それより前の環境では、内部結合や EXISTS で同じことを書きます。
● 起動中…

この問題で使えるテーブル(名前をタップすると入力できます)

10

NULL
🔑int不可
int不可
date不可
text不可
データを見る(先頭 5 行)
juchu_idkokyaku_idjuchu_onstatus
100112025-11-05done
100222025-11-18done
100312025-12-02done
100432025-12-09cancel
100542025-12-24done

17

NULL
🔑int不可
🔑int不可
int不可
int不可
numeric(10,0)不可
データを見る(先頭 5 行)
juchu_idgyo_noshohin_idsuryotanka
10011120180
10012230120
100214223800
100225118500
10031644200

5

NULL
🔑int不可
text不可
text
date不可
データを見る(先頭 5 行)
kokyaku_idkokyaku_nameprefcreated_on
1青葉工業東京都2024-05-10
2白樺物産大阪府2024-08-01
3黒松システム東京都2025-01-15
4赤坂商会NULL2025-03-20
5三田商事愛知県2025-06-01

7

NULL
🔑int不可
text不可
text不可
numeric(10,0)不可
データを見る(先頭 5 行)
shohin_idshohin_namecategoryprice
1ノート文具180
2ボールペン文具120
3付箋文具250
4デスクチェア家具24800
5書棚家具18500

解説

結論

「両方にある」を求めるのが INTERSECT です。

なぜ

UNION が「どちらかにある」、INTERSECT が「両方にある」、EXCEPT が「一方にあってもう一方に無い」です。この 3 つは集合演算と呼ばれ、いずれも重複を取り除いた結果を返します(ALL を付けると残ります)。

★取消の除外が効いているか: このデータには、ある年の受注が取消だけ、という顧客がいます。取消の条件を書かないと「その年にも受注があった」ことになり、結果に混ざります。条件を書いたつもりでも、それが結果を変えるデータでなければ検証できません。

★同じことは結合や EXISTS でも書けます。INTERSECT の利点は、2 つの条件を対等に並べて書けるため、「両方を満たす」という意図が読み手にそのまま伝わることです。一方、2 つの SELECT が長くなると重複した記述が増えるので、共通部分が多い場合は WITH で下ごしらえをしてから使うと読みやすくなります。

よくある間違い

①UNION と取り違える。②列の数や並びがそろっていない。③片方の SELECT にだけ条件を書く。

根拠(一次情報)