6. GROUP BY
• GROUP BY
• GROUP BY は複数のレコードを1行にまとめる場合に使用します。
• 集約関数(COUNT, SUM, MAX, MIN, AVGなど)と組み合わせて使用する場合が
多いです。
• 集約関数の結果に対して絞り込み条件を指定する場合は、HAVING句を使用し
ます。
6
-- 例
SELECT column1, SUM(column2), COUNT(*)
FROM table1
GROUP BY column1
HAVING SUM(column2) > 10000;
7. GROUP BY
• GROUP BY
• 集約関数を適用しないカラムで絞り込みを行う場合、WHERE句で絞り込む方
法とHAVING句で絞り込む方法があります。
• 結果は同じになりますが、パフォーマンスに差が出る場合があります。
7
-- 例①
SELECT column1, SUM(column2)
FROM table1
WHERE column1 = 200
GROUP BY column1 ;
-- 例②
SELECT column1, SUM(column2)
FROM table1
GROUP BY column1
HAVING column1 = 200;
33. UNION
• UNIONとUNION ALL
• 3つのSELECT文の和集合の結果を得るための演算子。
• UNION と UNION ALL の違いは、SELECT文①とSELECT文②に重複があっ
た場合に現れる。
• UNIONは、重複はまとめて表示する。UNION ALL は、重複もそのまま
表示する。
• パフォーマンス的にはUNION ALLの方が速い。UNIONは、重複排除のた
めにソートを行うが、UNION ALLではソートを行わないため。
33
-- 書き方
SELECT文①
UNION
SELECT文②
-- 書き方
SELECT文①
UNION ALL
SELECT文②
47. サブクエリ
• スカラ・サブクエリ
• SELECT句の中にサブクエリを記述する方法。
• 結果がイメージしやすいが、多用するとパフォーマンスが悪くなる。
47
-- SELECT句の中で、別のテーブルのレコードを取得する
SELECT id
, (SELECT name
FROM table2
WHERE id = table1.id) エイリアス名
FROM table1
49. CASE式
• CASE式
• SQLで条件分岐をするための構文
• SELECT句、WHERE句、GROUP BY句のなど、どこでも使用可能。
• 一般的にはWHERE句では使用しない。SELECT句の中で使用する。
• maxや、sumなどの集約関数の中に入れ込むこともある。
49
-- 書き方
SELECT
CASE
WHEN 条件式1 THEN 値1
WHEN 条件式2 THEN 値2
ELSE 値3
END エイリアス名
FROM table2
51. CASE式
• CASE式(解答)
51
-- 単価によってランクを決める
SELECT *
, CASE
WHEN 単価 >= 10000 THEN '高級品'
WHEN 単価 BETWEEN 5000 AND 9999 THEN '普通'
ELSE '安物'
END ランク
FROM 商品_CASE用
商品_CASE用
商品id 商品名 単価
001 商品A 1000
002 商品B 5000
003 商品C 10000
商品id 商品名 単価 ランク
001 商品A 1000 安物
002 商品B 5000 普通
003 商品C 10000 高級品
52. ウィンドウ関数
• ウィンドウ関数
• GROUP BY を使わずとも集約関数の結果を取得できる関数。
• row_number, count, sum, max, rank, dense_rank などがあります。
• 使いこなせると非常に便利ですが、DBMSによっては実装されておらず、
使用できないものもあるので注意が必要です。
• 関数名() over(…) のように使用します。overの中にはpartition by句と
order by句が記述できます。
52
-- 例
SELECT
row_number() over(partition by column1 order by column2)
, count() over(partition by column3 order by column4)
FROM table1
75. SQLの速度
• INとEXISTS
• サブクエリで条件指定してレコードを取得する場合、INによる書き方
とEXISTSによる書き方があります。
• 下の2つの書き方は同じ結果になります。どちらがパフォーマンス的
にすぐれているでしょうか。
75
-- EXISTSの場合
SELECT *
FROM products p
WHERE EXISTS (SELECT * FROM sales
WHERE products_id = p.products_id);
-- INの場合
SELECT *
FROM products p
WHERE products_id IN (SELECT products_id FROM sales);
77. SQLの速度
• 結合+DISTINCTとEXISTS
• INやEXISTSと同じ結果を得るために、結合を用いることもできます。
• ただし結合を使用する場合は、結果を一意にするためにDISTINCTが必
要な場面もあります。
77
-- EXISTSの場合
SELECT *
FROM products p
WHERE EXISTS (SELECT * FROM sales
WHERE products_id = p.products_id)
-- 結合の場合
SELECT DISTINCT p.*
FROM products p
INNER JOIN sales s
ON p.products_id = s.products_id
79. SQLの速度
• UNIONとUNION ALL
• UNIONとUNION ALL では、UNION ALLの方が高速です。
• 理由は、UNIONは重複削除のためにソートの処理を行うためです。
• そのため、重複がないことが分かっている場合や、ソートの必要がな
い場合はUNION ALLを使用することにしましょう。
79
80. SQLの速度
• HAVINGとWHERE
• GROUP BY句を使用する場合、HAVING句とWHERE句による絞り込みが可
能です。例えば以下の2つのSQL文は同じ結果になります。
80
-- HAVINGの場合
SELECT category_id, COUNT(*), MAX(products_id), MIN(products_id)
FROM products_2
GROUP BY category_id
HAVING category_id = 3
-- WHEREの場合
SELECT category_id, COUNT(*), MAX(products_id), MIN(products_id)
FROM products_2
WHERE category_id = 3
GROUP BY category_id