#Max値を含む行を抽出する方法
###やりたいこと
例えば、次のようなケースを想定する。
社員名簿には、社員名・社員の所属部署・社員の給料のデータが含まれる。
所属部署ごとに、給料が最大の社員の行を抽出したい。
下記のテーブル(employee)を想定する。
id | Name | Department | Salary |
---|---|---|---|
1 | Tanaka | Sales | 500 |
2 | Suzuki | Sales | 600 |
3 | Yamada | Sales | 1000 |
4 | Nakano | Accounting | 650 |
5 | Inoue | Accounting | 550 |
6 | Nomura | Accounting | 450 |
7 | Nakajima | Research | 900 |
8 | Sugiyama | Research | 700 |
9 | Hayashi | Research | 1100 |
###実行環境
PostgreSQL
pgAdmin4
###Max行取得の実現方法
1.Max値を特定する-集約関数/分析関数の利用
2.特定したMax値を含む行を抽出する-JOINの利用
1.Max値を特定する-集約関数/分析関数の利用
まずは、各部署ごとの給料の最大値を特定する。
集約関数を利用する場合、group byで所属ごとに集約し、Maxの給料を表示する。
select Department, Max(salary) as MaxSalary
from Employee
group by Department
表示結果
Department | MaxSalary |
---|---|
Accounting | 650 |
Research | 1100 |
Sales | 1000 |
分析関数(window関数)を利用しても、partition byで所属ごとのmaxの給料を表示できる。
select id, Name, Department, Max(salary) over(partition by department) as MaxSalary
from Employee
表示結果
id | Name | Department | MaxSalary |
---|---|---|---|
4 | Nakano | Accounting | 650 |
6 | Nomura | Accounting | 650 |
5 | Inoue | Accounting | 650 |
9 | Hayashi | Research | 1100 |
7 | Nakajima | Research | 1100 |
8 | Sugiyama | Research | 1100 |
1 | Tanaka | Sales | 1000 |
3 | Yamada | Sales | 1000 |
2 | Suzuki | Sales | 1000 |
2.特定したMax値を含む行を抽出する-JOINの利用
employeeテーブルと、1で作成したテーブルをjoinで結合する。
集約関数を利用した場合。
select emp_1.id, emp_1.Name, emp_1.Department, emp_1.Salary
from employee as emp_1
inner join
(select Department, Max(salary) as MaxSalary
from Employee
group by Department )
as emp_2
on emp_1.Department = emp_2.Department and emp_1.Salary = emp_2.MaxSalary
表示結果
id | Name | Department | Salary |
---|---|---|---|
3 | Yamada | Sales | 1000 |
4 | Nakano | Accounting | 650 |
9 | Hayashi | Research | 1100 |
分析関数を利用した場合。
select emp_1.id, emp_1.Name, emp_1.Department, emp_1.Salary
from employee as emp_1
inner join
(select id, Max(salary) over(partition by department) as MaxSalary
from Employee)
as emp_2
on emp_1.id = emp_2.id and emp_1.Salary = emp_2.MaxSalary
表示結果
id | Name | Department | Salary |
---|---|---|---|
4 | Nakano | Accounting | 650 |
9 | Hayashi | Research | 1100 |
3 | Yamada | Sales | 1000 |
分析関数を用いると、on句でidが同じことも結合条件に加えられるので、分析関数を用いた方が良いですね。
(今回は問題ないけど、idで結合条件を書けない集約関数を用いた場合、うまくいかないことがある。)