SELECT構文の構造
SELECT [ALL|DISTINCT] カラム名 [計算式]...
FROM テーブル名 [テーブル名2...]
[WHERE 条件式]
[GROUP BY カラム名 [カラム名2...]]
[HAVING 集約条件]
[ORDER BY カラム名 [ASC|DESC] [カラム名2...]]
- ALLは重複行を保持、DISTINCTは重複排除
- WHEREで行単位のフィルタリング
- GROUP BYでグループ化後にHAVINGでグループフィルタ
- ORDER BYで最終結果のソート
実行順序の理解
- FROMで指定されたテーブルの結合
- WHERE条件による行選択
- GROUP BYによるグループ化
- HAVING条件によるグループ選択
- SELECTカラムの投影
- ORDER BYによるソート
基本クエリ例
-- 年俸2万~3万の従業員情報取得
SELECT 従業員ID, 名前, 年俸/12 AS 月給
FROM 従業員マスタ
WHERE 年俸 BETWEEN 20000 AND 30000;
-- 東京または大阪支店の検索
SELECT *
FROM 支店情報
WHERE 支店名 IN ('東京本店', '大阪支店');
パターンマッチング
-- 大阪住所を持つオーナー検索
SELECT *
FROM オーナー情報
WHERE 住所 LIKE '%大阪%';
- %:0文字以上の任意文字列
- _:1文字のワイルドカード
- ESCAPEで特殊文字をエスケープ
ソート処理
-- 年俸降順で従業員一覧
SELECT 従業員ID, 年俸
FROM 従業員マスタ
ORDER BY 年俸 DESC;
-- 複合ソート(部署昇順→年俸降順)
SELECT 部署ID, 年俸
FROM 従業員マスタ
ORDER BY 部署ID, 年俸 DESC;
集約処理
-- 5月の物件閲覧数集計
SELECT COUNT(DISTINCT 物件ID), SUM(閲覧数)
FROM 閲覧記録
WHERE 閲覧日 BETWEEN '2023-05-01' AND '2023-05-31';
- COUNT(*)はNULLを含む行数カウント
- 他の集約関数はNULLを無視
グループ化処理
-- 部署別従業員数と給与合計
SELECT 部署ID,
COUNT(従業員ID) AS 配属数,
SUM(年俸) AS 総給与
FROM 従業員マスタ
GROUP BY 部署ID
HAVING COUNT(従業員ID) > 1;
HAVING使用時の注意点
- HAVINGはGROUP BY必須
- SELECTリストの非集約カラムはGROUP BY必須
- HAVINGの条件は集約関数に限る
WHEREとHAVINGの比較
-- 正しい使用例(平均点90以上)
SELECT 学生ID, AVG(点数)
FROM 成績表
GROUP BY 学生ID
HAVING AVG(点数) >= 90;
-- 間違った使用例(WHEREで集約関数使用不可)
SELECT 学生ID, AVG(点数)
FROM 成績表
WHERE AVG(点数) >= 90 -- エラー
GROUP BY 学生ID;