重複排除によるデータ抽出(DISTINCT)
結果セット内の重複を排除して一意の値のみ取得するには、DISTINCTキーワードを使用します。
SELECT DISTINCT column_a, column_b FROM data_table;
取得行数の制限(LIMIT および OFFSET)
大量のデータから特定の範囲のレコードを取得する場合、LIMITとOFFSETが有効です。初期位置は0から始まります。
SELECT * FROM data_table LIMIT 10; -- 最初の10件
SELECT * FROM data_table LIMIT 5 OFFSET 10; -- 11件目から5件取得
並べ替え(ORDER BY)
結果を昇順または降順で整列できます。
SELECT * FROM data_table ORDER BY created_at ASC; -- 昇順
SELECT * FROM data_table ORDER BY score DESC; -- 降順
データの集計(GROUP BY)
共通の値を持つ行をグループ化し、集計関数とともに使用します。
SELECT category, COUNT(*) AS count_per_category
FROM products
GROUP BY category;
テーブル結合操作
内部結合(INNER JOIN)
両方のテーブルに一致するキーがある場合のみ、そのデータを返します。
SELECT u.name, o.order_id
FROM users u
INNER JOIN orders o ON u.id = o.user_id;
外部結合
一致しない行も含めて結果を得たい場合に利用します。
左外部結合(LEFT JOIN)
SELECT u.name, o.order_id
FROM users u
LEFT JOIN orders o ON u.id = o.user_id; -- ユーザー全員を表示、注文がない場合はNULL
右外部結合(RIGHT JOIN)
SELECT p.product_name, s.sale_date
FROM sales s
RIGHT JOIN products p ON s.product_id = p.id; -- 商品全件を対象に売上情報を結合
複数クエリの統合(UNION)
異なるクエリの結果を一つにまとめることが可能です。
重複排除版
SELECT email FROM active_users
UNION
SELECT email FROM pending_users;
重複保持版
SELECT name FROM team_a
UNION ALL
SELECT name FROM team_b; -- 同名もすべて含む
副問い合わせ(Subquery)
あるクエリの中で別のSELECT文をネストして使用します。特に条件付き抽出に有効です。
SELECT * FROM employees
WHERE department_id IN (SELECT id FROM departments WHERE location = 'Tokyo');
条件式による絞り込み(WHERE 句)
基本比較演算子
SELECT * FROM items WHERE price > 1000;
SELECT * FROM logs WHERE status != 'failed';
BETWEENによる範囲指定
SELECT * FROM temperature_records
WHERE value BETWEEN 20 AND 30;
NULL値の判定
SELECT * FROM users WHERE phone IS NULL;
INによる複数値マッチング
SELECT * FROM products WHERE category_id IN (1, 3, 5);
論理演算子(AND / OR)
SELECT * FROM accounts
WHERE age >= 18 AND country = 'Japan';
SELECT * FROM logs
WHERE error_level = 'critical' OR duration > 1000;
NOTによる条件反転
SELECT * FROM files WHERE file_type NOT IN ('tmp', 'log');
SELECT * FROM users WHERE name NOT LIKE 'test%';
正規表現によるパターンマッチ(REGEXP)
文字列に対して高度なパターン検索を行えます。
SELECT * FROM emails
WHERE address REGEXP '^[a-zA-Z]+@company\\.com$';
グループ後の条件絞り込み(HAVING)
GROUP BY後に集計結果に対するフィルタリングを行う場合にHAVINGを使用します。
SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department
HAVING avg_salary > 5000000;
存在確認(EXISTS)
サブクエリの結果が1行以上存在するかどうかを判定します。
SELECT * FROM customers c
WHERE EXISTS (
SELECT 1 FROM orders o
WHERE o.customer_id = c.id AND o.year = 2023
);
仮想テーブル:ビュー(VIEW)の活用
頻繁に使用する複雑なクエリを簡略化するためにビューを作成できます。
CREATE VIEW high_value_customers AS
SELECT id, name, total_spent
FROM customers
WHERE total_spent > 100000;
- 利点:複雑なJOINを隠蔽、アクセス制御、計算カラムの定義が可能
- 欠点:パフォーマンスの低下、基盤テーブルへの依存性
その他の高機能オブジェクト
ストアドプロシージャ
複数のSQL文をまとめた再利用可能な手続きです。トランザクション管理にも適しています。
カーソル
ストアドプロシージャ内で結果セットを1行ずつ処理したい場合に使用します。
トリガー
INSERT、UPDATE、DELETEなどのイベント発生時に自動実行される仕組みです。監査ログやデータ整合性維持に有用です。
排他制御(ロック取得)
トランザクション中に他の接続による変更を防ぐために行ロックを取得できます。
SELECT * FROM inventory
WHERE item_id = 101 FOR UPDATE;