Leetcode的SQL題解:185. 部門工資前三高的員工

題目

查詢部門工資前三高的員工。html

我用的數據庫是oracle。 下面是數據表的信息。 Employee表數據:mysql

| ID | NAME | Salary | DepartmentId |
| -- | ---- | ------ | ------------ |
|1 |	Joe	    |   85000	|   1   |
|2 |	Henry	|	80000	|	2	|
|3 |	Sam	    |	60000	|	2	|
|4 |	Max	    |	90000	|	1	|
|5 |	Janet	|	69000	|	1	|
|6 |	Randy	|	85000	|	1	|
|7 |	Will	|	70000	|	1	|
|8 |	edav	|	50000	|	2	|
|9 |	easonv	|	40000	|	2	|

八、9行爲我自行添加,爲了更清晰展現查詢結果。sql

建立表

Employee 表包含全部員工信息,每一個員工有其對應的 Id, salary 和 department Id 。數據庫

create table Employee (
  Id number(5),
  Name varchar2(10) ,
  Salary number(5),
  DepartmentId number(5)
);

Department 表包含公司全部部門的信息。oracle

create table Department  (
  Id number(5),
  Name varchar2(10) 
);

插入數據Employee,腳本以下函數

insert into Employee (ID, NAME, SALARY, DEPARTMENTID)
values ('1', 'Joe', '85000', '1');

insert into Employee (ID, NAME, SALARY, DEPARTMENTID)
values ('2', 'Henry', '80000', '2');

insert into Employee (ID, NAME, SALARY, DEPARTMENTID)
values ('3', 'Sam', '60000', null);

insert into Employee (ID, NAME, SALARY, DEPARTMENTID)
values ('4', 'Max', '90000', '1');

insert into Employee (ID, NAME, SALARY, DEPARTMENTID)
values ('5', 'Janet', '69000', '1');

insert into Employee (ID, NAME, SALARY, DEPARTMENTID)
values ('6', 'Randy', '85000', '1');

insert into Employee (ID, NAME, SALARY, DEPARTMENTID)
values ('7', 'Will', '70000', '1');

insert into Employee (ID, NAME, SALARY, DEPARTMENTID)
values ('8', 'eda', '50000', '2');

insert into Employee (ID, NAME, SALARY, DEPARTMENTID)
values ('9', 'eason', '40000', '2');

插入數據Department,腳本以下性能

insert into Department (ID, NAME)
values ('1', 'IT');

insert into Department (ID, NAME)
values ('2', 'Sales');

查詢

如下使用四種SQL語句查出的結果,前兩個是用oracle特有函數,後兩個是標準SQL92寫法。spa

你以爲哪一個對?哪一個性能高?code

函數1 ROW_NUMBER

select Department,Employee,Salary
 from (select (ROW_NUMBER()
               over(PARTITION by t1.departmentid order by Salary desc)) lev,
              t2.name Department,
              t1.name Employee,
              t1.Salary Salary
         from Employee t1, Department t2
        where t1.departmentid = t2.id) A
where lev <= 3;

函數2 dense_rank

select D.Name Department, E.Name Employee, E.Salary Salary
	from (select Name,
														Salary,
														DepartmentId,
														dense_rank() over(partition by DepartmentId order by Salary desc) Trank
									from Employee) E
right join Department D
			on E.DepartmentId = D.id
where Trank <= 3;

通用寫法1

select d.name as Department, e.name as Employee, e.salary as Salary
  from employee  e
 inner join department  d
    on e.DepartmentId = d.id
 where  (select count(distinct salary)
          from employee
         where salary > e.salary
           and departmentid = e.DepartmentId) < 3
 order by e.departmentid, Salary desc;

通用寫法2

SELECT t3.name Department, t2.name Employee, t2.salary Salary
	FROM Employee t2, Department t3
WHERE t2.id NOT IN (SELECT b.id
						FROM Employee a, Employee b
						WHERE a.DepartmentId = b.DepartmentId
								AND a.salary > b.salary
								GROUP BY b.id
								HAVING COUNT(*) >= 3)
		AND t2.DepartmentId = t3.id
ORDER BY Department, t2.salary DESC;

吐槽

感興趣的同窗能夠本身跑下。htm

我我的以爲所謂官方答案是有問題的。

官方題解以下,mysql版本:

SELECT d.Name AS 'Department', e1.Name AS 'Employee', e1.Salary
	FROM Employee e1
	JOIN Department d
			ON e1.DepartmentId = d.Id
    WHERE 3 > (SELECT COUNT(DISTINCT e2.Salary)
				FROM Employee e2
				WHERE e2.Salary > e1.Salary
			AND e1.DepartmentId = e2.DepartmentId);

改寫成oracle版,加上排序:

SELECT d.Name Department, e1.Name Employee, e1.Salary
	FROM Employee e1
	JOIN Department d
			ON e1.DepartmentId = d.Id
    WHERE 3 > (SELECT COUNT(DISTINCT e2.Salary)
				FROM Employee e2
				WHERE e2.Salary > e1.Salary
			AND e1.DepartmentId = e2.DepartmentId)
	 order by d.id,salary desc

查出來的數據是與通用寫法1同樣的, 兩個一樣的85000的數據

|序號| Department | Employee | Salary |
|--- | ---- | ------- | ------------ |
|1 |	IT  |	Max   |	90000
|2 |	IT  | 	Randy |	85000
|3 |	IT  |	Joe   |	85000
|4 |	IT  |	Will  |	70000
|5 |	Sales |	Henry |	80000
|6 |	Sales |	Sam   |	60000
|7 |	Sales |	eda|	50000

這個題目出的歧義太大,若是是在考試中,應該是查出前三名、前四名的都對。

我的認爲應該查出前三名應該是不包含70000這條數據的,就算是並列第二,那麼就應該沒有第三了,高校排名不也是這樣嗎?

因此私覺得正確答案應該是查出這樣的數據

|序號| Department | Employee | Salary |
|--- | ---- | ------- | ------------ |
|1 |	IT  |	Max   |	90000
|2 |	IT  | 	Randy |	85000
|3 |	IT  |	Joe   |	85000
|4 |	Sales |	Henry |	80000
|5 |	Sales |	Sam   |	60000
|6 |	Sales |	eda|	50000

那麼,我寫的四條語句中,應該是函數1及通用寫法2能夠知足這個條件。


個人公衆號

原文出處:https://www.cnblogs.com/yaomaomao/p/11133437.html

相關文章
相關標籤/搜索