元の質問:https:
//leetcode-cn.com/problems/department-highest-salary/ leetcodeのデータベース問題の問題解決レコードを作成しました:
Problem-solving directory https://blog.csdn.net/weixin_42845682/article/詳細/ 105196004
タイトルの説明:
Employeeテーブルにはすべての従業員情報が含まれ、各従業員には対応するID、給与、および部門IDがあります。
+----+-------+--------+--------------+
| Id | Name | Salary | DepartmentId |
+----+-------+--------+--------------+
| 1 | Joe | 70000 | 1 |
| 2 | Henry | 80000 | 2 |
| 3 | Sam | 60000 | 2 |
| 4 | Max | 90000 | 1 |
+----+-------+--------+--------------+
Departmentテーブルには、会社のすべての部門に関する情報が含まれています。
+----+----------+
| Id | Name |
+----+----------+
| 1 | IT |
| 2 | Sales |
+----+----------+
SQLクエリを記述して、各部門で最も給与の高い従業員を見つけます。たとえば、上記の表によると、マックスはIT部門で最高の給与を、ヘンリーはセールス部門で最高の給与を持っています。
+------------+----------+--------+
| Department | Employee | Salary |
+------------+----------+--------+
| IT | Max | 90000 |
| Sales | Henry | 80000 |
+------------+----------+--------+
回答:
最初の答え
最初はこの質問はとても単純だと感じましたが、後で少し難しいと思いました。テーブル構造を設計するなら、給与テーブルと従業員個人情報テーブルを確実に分離します。
select
department Department,
e1.name Employee,
tmp.salary Salary
from employee e1
join (
select
d.name department,
d.id id,
max(salary) salary
from employee e
join department d on e.departmentId = d.id
group by d.name,d.id
) tmp on e1.salary = tmp.salary and e1.departmentId = tmp.id
group by tmp.department, e1.name
書いてテストに合格しましたが、見ているといつも変な感じがしました。
アイデアは、まず部門の最高の給与を見つけ、次に部門と給与を使用して従業員テーブルを結合します(同じ最高の給与を持つ部門が複数ある場合があるため、部門の処理資金を使用します)。
しかし、従業員の名前が奇妙であると常に感じて、同じ名前を考慮しないと言う方法は?そしてタイトルは部門の2人が最高の給与のために結ばれているかどうか迷惑であるかどうか示す方法を言わなかった。
第二の答え
実際、この種のセグメンテーションは、row_number()でも実行できます。
select
dname department,
ename employee,
salary
from(
select
d.name dname,
e.name ename,
e.salary,
row_number() over(partition by d.name order by salary desc) row_num
from employee e
join department d on e.departmentId=d.id
) tmp
where row_num = 1
送信時にエラーが発生しました。それを見て、出力を期待しました。部門に同じくらい高い2つの賃金がある場合、両方が出力されるはずです。そのrow_number()はもう機能してはなりません。。。
ただし、dense_rank()またはrank()に変更することをお勧めします。
select
dname department,
ename employee,
salary
from(
select
d.name dname,
e.name ename,
e.salary,
dense_rank() over(partition by d.name order by salary desc) row_num
from employee e
join department d on e.departmentId=d.id
) tmp
where row_num = 1
吐き出すために:これらの重複するデータを処理する方法についての具体的な説明はありません; Oracleの提出も本当に面倒です...
しばらく残業しています:
これを書いたようで、効率は非常に高いです。