SELECT *
FROM employees
WHERE salary = (SELECT MAX(salary) FROM employees);
出力例:
employee_id
name
salary
department_id
101
Tanaka
120000
1
このクエリの仕組み:
サブクエリ (SELECT MAX(salary) FROM employees) が最高給与を取得。
外側のクエリが、その最高給与を持つレコード全体を取得。
方法2: JOINを使用する
JOINを使うと、より柔軟なクエリを作成できます。
例: 部署ごとに最高給与を持つ従業員の情報を取得
SELECT e.*
FROM employees e
JOIN (
SELECT department_id, MAX(salary) AS max_salary
FROM employees
GROUP BY department_id
) subquery
ON e.department_id = subquery.department_id AND e.salary = subquery.max_salary;
出力例:
employee_id
name
salary
department_id
101
Tanaka
120000
1
202
Suzuki
90000
2
このクエリの仕組み:
サブクエリで、部署ごとに最高給与を計算。
メインクエリがその最大給与を持つ従業員のレコード全体を取得。
方法3: ウィンドウ関数を使用する(MySQL 8.0以降)
MySQL 8.0以降では、ウィンドウ関数を使うことで、より簡潔かつ効率的に最大値のレコードを取得できます。
例: 部署ごとに最高給与を持つ従業員を取得
SELECT employee_id, name, salary, department_id
FROM (
SELECT *,
RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rnk
FROM employees
) ranked
WHERE rnk = 1;
出力例:
employee_id
name
salary
department_id
101
Tanaka
120000
1
202
Suzuki
90000
2
このクエリの仕組み:
RANK()関数で、各部署内での給与順にランク付け。
外側のクエリでランクが1のレコードを抽出(最大値を持つレコード)。
注意点
複数のレコードが最大値を持つ場合
最大値が複数のレコードで重複する場合、どちらの方法でもすべての該当レコードが取得されます。 例:
SELECT *
FROM employees
WHERE salary = (SELECT MAX(salary) FROM employees);
SELECT *
FROM products
WHERE price = (SELECT MAX(price) FROM products);
プロジェクトごとに最大コストの詳細を取得
SELECT p.*
FROM projects p
JOIN (
SELECT project_id, MAX(cost) AS max_cost
FROM project_costs
GROUP BY project_id
) subquery
ON p.project_id = subquery.project_id AND p.cost = subquery.max_cost;
SELECT MAX(salary) FROM employees WHERE department_id = 1;
クエリの最適化: 不要な計算を排除し、シンプルなクエリ構造を保つこと。
Q6: MAX関数とGROUP BY句を組み合わせた場合、どのような結果になりますか?
A6: GROUP BY句とMAX関数を組み合わせると、グループごとの最大値を取得できます。
例: 部署ごとの最高給与を取得
SELECT department_id, MAX(salary)
FROM employees
GROUP BY department_id;
結果:
department_id
MAX(salary)
1
120000
2
90000
Q7: 複数の最大値を持つレコードが存在する場合、どうすれば全て取得できますか?
A7: サブクエリやJOINを使用することで、複数の最大値を持つレコードを取得できます。
例: 最大値を持つ全レコードを取得
SELECT *
FROM employees
WHERE salary = (SELECT MAX(salary) FROM employees);
Q8: MAX関数はウィンドウ関数と併用できますか?
A8: はい、MySQL 8.0以降では、ウィンドウ関数と併用することで柔軟なクエリが可能です。
例: 部署ごとの最高給与を持つ従業員を取得
SELECT employee_id, name, salary, department_id
FROM (
SELECT *,
RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rnk
FROM employees
) ranked
WHERE rnk = 1;