UNION
CoddyのSQLジャーニー「基礎」セクションの一部。レッスン 48/72。
UNIONは結合とは異なります。結合 では条件を使ってテーブルを組み合わせますが、UNION では単に2つのテーブルを上下に追加します。UNIONを使うには、次のように記述します。
SELECT col1, col2, ... FROM table1
UNION
SELECT col1, col2, ... FROM table2両方のSELECTは、次のルールに従う必要があります。
- 列の数は同じでなければなりません
- 順序が重要です
- 同じ位置にある列には、同じ種類のデータが格納されている必要があります(SQLiteは列の型をチェックしません)
たとえば、次のテーブルがあるとします。
germany_people
| id | name |
| 1 | Lena |
| 2 | Leonie |
england_people
| id | name |
| 1 | George |
| 2 | Lena |
問題:手元にあるすべての名前をまとめた大きなテーブルを作りたいとします。
SELECT name from germany_people
UNION
SELECT name from england_people結果:
| name |
| Lena |
| Leonie |
| George |
UNIONは重複しない値のみを返しますが、UNION ALLはすべてのレコードをそのまま返します:
SELECT name from germany_people
UNION ALL
SELECT name from england_people結果:
| name |
| Lena |
| Leonie |
| George |
| Lena |
UNION ALLを集計関数、GROUP BY、ORDER BYと組み合わせると、複数のテーブルにまたがるデータを要約することもできます。ポイントは、UNION ALLをサブクエリで囲み、その上にグループ化と並べ替えを適用することです。
たとえば、両方のテーブルで各名前が何回出現するかを数えたいとします。
SELECT name, COUNT(*) AS total_count
FROM (
SELECT name FROM germany_people
UNION ALL
SELECT name FROM england_people
) AS combined
GROUP BY name
ORDER BY total_count DESC結果:
| name | total_count |
| Lena | 2 |
| Leonie | 1 |
| George | 1 |
ここでは、Lenaのような重複を残すために、UNIONではなくUNION ALLを使用します。そうしないと、集計する前に重複が削除されてしまいます。サブクエリですべての行を結合し、その後GROUP BY + COUNTで集計します。ORDER BYで最終結果を並べ替えます。
チャレンジ
簡単利用可能なテーブルと列:
sales_2009:product_id,quantity_soldsales_2010:product_id,quantity_soldsales_2011:product_id,quantity_sold
売上テーブルは3つあります。
すべてのテーブルをまとめて、各商品の売上合計を求めてください。
結果にはproduct_idと売上合計を含めてください。
この列の名前をtotal_salesにしてください。
売上合計の降順で結果を並べ替えてください。
自分で試してみよう
-- すべての行を残したまま、3つのテーブルを1つの結果にまとめる
SELECT product_id, ____ AS total_sales
FROM (
SELECT * FROM sales_2009
____
SELECT * FROM sales_2010
____
SELECT * FROM sales_2011
)
-- 製品ごとに1行とし、合計が大きい順に並べる
GROUP BY ____
ORDER BY ____ DESC;このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
基礎のすべてのレッスン
自分で練習してみよう: SQLプレイグラウンド