【保存版】SQLでSELECT結果を統合!UNION、UNION ALL、INTERSECT、EXCEPTを使いこなそう
SQL で複数の SELECT コマンドの結果を 1 つのクエリに結合するには、いくつかの方法があります。 それぞれ異なる用途に適しているので、状況に応じて適切な方法を選択する必要があります。
方法
UNION オペレータは、2 つの SELECT コマンドの結果を結合する最も基本的な方法です。 重複する行を削除せずに、両方のクエリからのすべての行を返します。
SELECT * FROM table1 UNION SELECT * FROM table2;
この例では、
table1
とtable2
のすべての行が返されます。 重複する行は削除されません。INTERSECT オペレータは、2 つの SELECT コマンドの結果で一致する行のみを返します。
SELECT * FROM table1 INTERSECT SELECT * FROM table2;
この例では、
table1
とtable2
の両方に存在する行のみが返されます。
JOIN
結合を使用して、複数のテーブルからデータを抽出することもできます。 結合は、テーブル間の関連行を結合するのに役立ちます。
SELECT * FROM table1
JOIN table2 ON table1.id = table2.id;
補足
- 上記の例はすべて、SQLite で動作します。他のデータベースシステムでは、構文がわずかに異なる場合があります。
例
次の例では、customers
テーブルと orders
テーブルのデータを使用して、各顧客の注文数を表示する方法を示します。
SELECT customers.name, COUNT(*) AS order_count
FROM customers
JOIN orders ON customers.id = orders.customer_id
GROUP BY customers.name;
このクエリは、次の結果を返します。
name | order_count
------- | --------
Alice | 3
Bob | 2
Charlie | 1
この例では、UNION
オペレータを使用して、2 つの SELECT コマンドの結果を結合しています。 最初の SELECT コマンドは、customers
テーブルからすべての顧客の名前を取得します。 2 番目の SELECT コマンドは、orders
テーブルから各顧客の注文数を取得します。
UNION
オペレータは、2 つのクエリからのすべての行を結合します。 重複する行は削除されません。
サンプルコード:顧客と注文数のリスト
-- customers テーブルを作成
CREATE TABLE customers (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
);
-- orders テーブルを作成
CREATE TABLE orders (
id INTEGER PRIMARY KEY,
customer_id INTEGER NOT NULL,
FOREIGN KEY (customer_id) REFERENCES customers(id)
);
-- サンプルデータ挿入
INSERT INTO customers (name) VALUES
('Alice'),
('Bob'),
('Charlie');
INSERT INTO orders (customer_id) VALUES
(1),
(1),
(1),
(2),
(2),
(3);
-- 顧客の名前と注文数をリストする
SELECT customers.name, COUNT(*) AS order_count
FROM customers
JOIN orders ON customers.id = orders.customer_id
GROUP BY customers.name;
このコードを実行すると、次の結果が出力されます。
name | order_count
------- | --------
Alice | 3
Bob | 2
Charlie | 1
説明
- テーブルの作成: 最初に、
customers
テーブルとorders
テーブルを作成します。customers
テーブルには、id
(主キー) とname
(顧客名) の列があります。orders
テーブルには、id
(主キー)、customer_id
(外部キー)、の列があります。customer_id
はcustomers
テーブルのid
列を参照します。
- サンプルデータの挿入: 次に、
customers
テーブルとorders
テーブルにサンプルデータ挿入します。customers
テーブルには、3人の顧客の名前が挿入されます。orders
テーブルには、6つの注文が挿入されます。 各注文は、customers
テーブルのid
列に対応する顧客に関連付けられています。
- クエリの発行: 最後に、
SELECT
クエリを実行して、顧客の名前と注文数をリストします。- このクエリは、
customers
テーブルとorders
テーブルをcustomer_id
列で結合します。 GROUP BY
句を使用して、顧客ごとに結果をグループ化します。COUNT(*)
関数を使用して、各顧客の注文数をカウントします。
- このクエリは、
SQL で 2 つの SELECT クエリの結果を結合するその他の方法
サブクエリを使用して、別のクエリの結果を列として参照できます。 これにより、複雑なクエリをより小さな部分に分割し、読みやすくすることができます。
SELECT *
FROM customers
WHERE id IN (
SELECT customer_id
FROM orders
WHERE product_id = 123
);
この例では、customers
テーブルから product_id = 123
の注文をすべて行った顧客を選択します。
WITH customer_orders AS (
SELECT customer_id, COUNT(*) AS order_count
FROM orders
GROUP BY customer_id
)
SELECT customers.name, order_count
FROM customers
JOIN customer_orders ON customers.id = customer_orders.customer_id;
この例は、前述のサンプルコードと同じ結果を返しますが、WITH
句を使用して customer_orders
という一時的な結果セットを定義しています。
COMMON TABLE EXPRESSION (CTE) を使用する
CTE は、WITH 句に似ていますが、より多くの機能を提供します。 CTE は、複数のクエリで使用したり、他のデータベースオブジェクトを参照したりすることができます。
CREATE TABLE orders_per_customer (
customer_id INTEGER,
order_count INTEGER
);
INSERT INTO orders_per_customer (customer_id, order_count)
SELECT customer_id, COUNT(*)
FROM orders
GROUP BY customer_id;
SELECT customers.name, order_count
FROM customers
JOIN orders_per_customer ON customers.id = orders_per_customer.customer_id;
この例は、orders_per_customer
という一時的なテーブルを作成し、そのテーブルを使用して顧客の名前と注文数をリストします。
レポートツールを使用する
多くのレポートツールでは、複数のクエリ結果を結合するためのビジュアルインターフェースを提供しています。 これらのツールを使用すると、コードを記述せずに複雑なクエリを作成できます。
上記の方法以外にも、SQL で 2 つの SELECT クエリの結果を結合する方法はいくつかあります。 最適な方法は、特定のニーズと要件によって異なります。
ヒント
- 複雑なクエリを作成する場合は、複数の小さなクエリに分割して、各クエリが何を達成しているのかを理解しやすくすることをお勧めします。
- サブクエリ、WITH 句、CTE を使用すると、クエリをより読みやすく、保守しやすくなります。
- レポートツールを使用すると、コードを記述せずに複雑なクエリを作成できます。
sql sqlite select