本文へスキップ
BecomeCoder

SQL データ操作 (DML)コース · 第7章 高度なクエリ · レッスン28

集合演算 ― UNION / INTERSECT / EXCEPT

ブラウザで完結

導入

「高額商品のリストと、在庫切れ商品のリストを、1つにまとめたい」。2つの SELECT結果どうしを、足したり・共通部分を取ったり・引いたりできるのが集合演算です。ベン図の「和・積・差」をそのまま SQL でやるイメージです。

説明

3つの演算があります。いずれも「2つの SELECT の列数と型がそろっている」ことが条件です。

flowchart LR
    A["UNION<br/>どちらかに含まれる<br/>(和・重複は1つに)"]
    B["INTERSECT<br/>両方に含まれる<br/>(積・共通部分)"]
    C["EXCEPT<br/>左にあって右にない<br/>(差)"]

UNION ― 2つの結果を1つに(重複は除去)

SELECT id, name FROM products WHERE price >= 100000
UNION
SELECT id, name FROM products WHERE stock = 0;

重複を消さずに全部つなぎたいときは UNION ALL を使います(そのぶん速い)。

EXCEPT ― 引き算。「一度も注文していない会員」は、「全会員」から「注文したことのある会員」を引けば求まります。

SELECT id FROM users
EXCEPT
SELECT user_id FROM orders;

orders に登場する user_id は 1〜5 なので、この結果は 6(山本さん)だけ。「該当しないもの」を出すのに集合演算が効くわかりやすい例です。

INTERSECT ― 共通部分。両方の SELECT に現れる行だけを返します。

やってみよう

初期表示の UNION を実行し、高額商品(ノートPC)と在庫切れ商品(Webカメラ)が1つのリストにまとまることを確認しましょう。次に上の EXCEPT の例を実行して、「一度も注文していない会員」だけが残ることを見てください。

演習

EXCEPT を使って、一度も注文されていない商品の id を求めてください(products の全 id から、order_items に登場する product_id を引きます)。

ヒント1を見る

SELECT id FROM products から SELECT product_id FROM order_items を引きます。

ヒント2を見る

SELECT id FROM products EXCEPT SELECT product_id FROM order_items;

実際に動かしてみよう

下のエディタにクエリを書いて「実行」を押すと、ブラウザ内のSQLiteで結果が表示されます。本文の例をそのまま試したり、書き換えたりしてみましょう。

SQL — ブラウザ内で実行(SQLite)

ブラウザ内でSQLを動かす環境(SQLite)を読み込みます(初回のみ一瞬)。
スクロールして表示された時点でも自動で読み込まれます。