← 学習トップに戻る

🗃️ SQL

リレーショナルデータベースの標準言語。SELECT・JOIN・集計関数・ウィンドウ関数・CTE を体系的に整理。

📌 基本 SELECT 構文

-- 基本形
SELECT col1, col2
FROM   table_name
WHERE  col1 = 'value'
ORDER BY col2 DESC
LIMIT  100;

-- DISTINCT: 重複排除
SELECT DISTINCT department FROM employees;

-- CASE 式
SELECT name,
       CASE WHEN salary >= 500000 THEN '高'
            WHEN salary >= 300000 THEN '中'
            ELSE '低' END AS salary_rank
FROM employees;

📌 WHERE 条件

演算子 / 構文意味・例
=, <>, <, >, <=, >=比較演算子
AND / OR / NOT論理演算子
BETWEEN a AND b範囲指定(a 以上 b 以下)
IN (v1, v2, ...)値リストに含まれる
LIKE 'A%'パターンマッチ(% は任意文字列、_ は1文字)
IS NULL / IS NOT NULLNULL 判定
EXISTS (subquery)サブクエリの結果が1行以上存在

📌 JOIN

-- INNER JOIN: 両テーブルに一致する行のみ
SELECT e.name, d.dept_name
FROM   employees e
INNER JOIN departments d ON e.dept_id = d.id;

-- LEFT JOIN: 左テーブルは全行、右テーブルは一致した行のみ
SELECT e.name, o.order_date
FROM   employees e
LEFT JOIN orders o ON e.id = o.emp_id;

-- CROSS JOIN: 直積(全組み合わせ)
SELECT a.val, b.val FROM tbl_a a CROSS JOIN tbl_b b;

-- 自己結合: 同一テーブルを別名で JOIN
SELECT e.name, m.name AS manager
FROM   employees e
LEFT JOIN employees m ON e.manager_id = m.id;

📌 集計関数 & GROUP BY

関数内容
COUNT(*)行数(NULLを含む)
COUNT(col)NULLを除いた行数
SUM(col)合計
AVG(col)平均
MAX(col) / MIN(col)最大値 / 最小値
SELECT   dept_id,
         COUNT(*) AS headcount,
         AVG(salary) AS avg_sal
FROM     employees
GROUP BY dept_id
HAVING   AVG(salary) > 400000
ORDER BY avg_sal DESC;

📌 ウィンドウ関数

-- ROW_NUMBER: グループ内の連番
SELECT name, dept_id, salary,
       ROW_NUMBER() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS rnk
FROM employees;

-- RANK / DENSE_RANK: 同順位考慮
RANK() OVER (ORDER BY salary DESC)        -- 同順位後はスキップ
DENSE_RANK() OVER (ORDER BY salary DESC)  -- スキップなし

-- LAG / LEAD: 前後の行の値を参照
LAG(salary, 1) OVER (ORDER BY hire_date)   -- 1行前
LEAD(salary, 1) OVER (ORDER BY hire_date)  -- 1行後

-- 累計合計
SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)

📌 CTE(WITH 句)

-- 共通テーブル式: 読みやすいサブクエリ
WITH dept_avg AS (
  SELECT dept_id, AVG(salary) AS avg_sal
  FROM   employees
  GROUP BY dept_id
),
high_earners AS (
  SELECT e.name, e.salary, da.avg_sal
  FROM   employees e
  JOIN   dept_avg da ON e.dept_id = da.dept_id
  WHERE  e.salary > da.avg_sal
)
SELECT * FROM high_earners ORDER BY salary DESC;

📌 DML(データ操作)

-- INSERT
INSERT INTO employees (name, dept_id, salary)
VALUES ('田中', 3, 380000);

-- UPDATE
UPDATE employees
SET    salary = salary * 1.05
WHERE  dept_id = 3;

-- DELETE
DELETE FROM employees
WHERE hire_date < '2000-01-01';

-- UPSERT (PostgreSQL)
INSERT INTO kv (key, value)
VALUES ('x', 1)
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;

🔗 参考リンク