スポンサーリンク

【応用情報技術者試験】データベースを学ぼう!     ~第6章~SQL② グループ集計、副問い合わせ

SQLと関係演算:抽出・結合・集計を整理 データベース

WHEREは集計前の行、HAVINGは集計後のグループを絞ります。副問い合わせは、別の検索結果を条件などに使う仕組みです。集計と存在チェックを、小さな表で順に確認しましょう。例は学習用の架空データです。

まず集計の材料になる行を確認

sale_idshopamount
1東店600
2東店900
3西店400
4西店700

sale_idは主キー、shop・amountはNULLではないものとします。

SELECT shop, SUM(amount) AS total
FROM sales
WHERE amount >= 500
GROUP BY shop
HAVING SUM(amount) >= 1000
ORDER BY SUM(amount) DESC;

400の行を除いてから店舗別に合計すると、東店1500・西店700です。HAVINGで1000以上を残すので、結果は東店1500の1行になります。これは結果を理解するための論理的な流れで、内部の物理的な実行順を固定する説明ではありません。

GROUP BY・HAVING・COUNTの確認点

項目確認点
GROUP BY同じ値の行をグループにまとめる
HAVINGグループや集計結果に条件を指定する
COUNT(*)行数を数える
COUNT(amount)amountがNULLでない行を数える
SUM・AVG通常はNULLを除いて計算。AVGの分母もNULLでない値の数

基本の集計問題では、SELECTに書く列がグループ化のキーか集計結果かを確認します。SQLには関数従属などによる例外もあるため、製品の規則や問題の前提にも注意します。HAVINGでSELECTの別名を使えるかもDBMSによります。

年の条件は開始と終了を指定する

SELECT shop, SUM(amount)
FROM sales_table
WHERE sales_date >= DATE '2025-01-01'
  AND sales_date < DATE '2026-01-01'
GROUP BY shop
HAVING SUM(amount) >= 100000;

2025年だけなら、開始日以降という条件だけでは2026年以降も含まれます。翌年の開始日未満まで指定します。例はDATE型を想定し、日付リテラルの構文は利用するDBMSに合わせます。

副問い合わせで平均と比べる

SELECT sale_id, amount
FROM sales
WHERE amount > (SELECT AVG(amount) FROM sales);

最初の4行の平均は650です。結果は900と700の2行になります。この形では比較に使う副問い合わせが1つの値を返す必要があります。複数行を返す検索と単純な等号比較を組み合わせると、エラーになる場合があります。

EXISTS・NOT EXISTSと相関副問い合わせ

SELECT c.customer_id, c.customer_name
FROM customers c
WHERE EXISTS (
  SELECT 1
  FROM orders o
  WHERE o.customer_id = c.customer_id
);

この例は顧客表customersと注文表ordersを想定しています。内側で外側のc.customer_idを参照するのが相関です。対応する注文が1行でもあればその顧客を残し、NOT EXISTSなら該当する注文がない顧客を残します。注文数が多くても、この存在条件だけで同じ顧客行が増えることはありません。

EXISTSは返された行の有無を判定します。SELECT 1はよく使う記法で、1という値自体を比較しているわけではありません。外側の行ごとに対応を考えると理解できますが、実際には最適化で別の実行方法が選ばれることもあります。INより必ず速いという保証はありません。

NOT INとNULLを慎重に扱う

通常の単一値比較では、5 NOT IN (1, NULL)は真にならず、WHEREではその行が残りません。NOT EXISTSは行の存在を判定しますが、内側の比較式にNULLがあれば、その比較は真にならないことがあります。NULLの行を一致として扱うかなど、求める結果を先に決めましょう。両者を機械的に置き換えるのは避けます。

確認問題

最初の売上表から「各売上が500以上」というWHEREだけを外し、店舗別合計1000以上をHAVINGで選ぶと、結果はどうなりますか?

解答・解説を見る

東店1500、西店1100の2行です。WHEREを外すと西店の400も集計対象になります。行を除く条件と、合計後にグループを除く条件は区別します。

基本構文は前章:SQL① 基本的なSELECT文から復習できます。

SQLをnoteの例題で復習する

基礎を確認したら、無料noteのSELECT・JOIN・GROUP BY・サブクエリの解説で、条件の読み取りとSQLの組み立てを復習できます。

無料note:SQL頻出ポイントをまとめて学ぶ

集計する行と集計後のグループの違いに迷ったら、WHERE・GROUP BY・HAVINGを例題で比較するnoteへ進みましょう。

資格・目的別のnote教材ナビから、ほかの分野も選べます。

参考資料

PostgreSQL:FROM・WHERE・GROUP BY・HAVING / ORDER BY / 副問い合わせの条件式

コメント