获取所有部门中当前员工薪水最高的相关信息,给出dept_no, emp_no以及其对应的salary
CREATE TABLE `dept_emp` (
`emp_no` int(11) NOT NULL,
`dept_no` char(4) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`dept_no`));
CREATE TABLE `salaries` (
`emp_no` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`from_date`));
输入描述:
无
输出描述:
dept_no | emp_no | salary |
---|---|---|
d001 | 10001 | 88958 |
d002 | 10006 | 43311 |
d003 | 10005 | 94692 |
d004 | 10004 | 74057 |
d005 | 10007 | 88070 |
d006 | 10009 | 95409 |
select d.dept_no,d.emp_no,max(s.salary) as salary
from dept_emp d
left join salaries s
on d.emp_no = s.emp_no
where d.to_date='9999-01-01'
and s.to_date='9999-01-01'
group by d.dept_no
此题思路如下:
我这种做法可以通过检测,但是看了其他网友的解析后,,我发现这种做法有问题,因为GROUP BY 默认取非聚合的第一条记录
漏洞:
解法一:(如果同部门有多条同等最大salary,一起显示出来)
select r.dept_no,ss.emp_no,r.maxSalary from (
select d.dept_no,max(s.salary)as maxSalary from dept_emp d,salaries s
where d.emp_no=s.emp_no
and d.to_date='9999-01-01'
and s.to_date='9999-01-01'
group by d.dept_no
)as r,salaries ss,dept_emp dd
where r.maxSalary=ss.salary
and r.dept_no=dd.dept_no
and dd.emp_no=ss.emp_no
and ss.to_date='9999-01-01'
and dd.to_date='9999-01-01'
order by r.dept_no asc
解法二:(如果同部门有多条同等最大salary,仅显示一条)
select r.dept_no,r.emp_no,max(r.salary) from (
select d.dept_no,d.emp_no,s.salary from dept_emp d,salaries s
where d.emp_no=s.emp_no
and d.to_date='9999-01-01'
and s.to_date='9999-01-01'
order by s.salary desc
)as r
group by r.dept_no
order by r.dept_no asc
注明两点:
1、方法一:使用窗口排序函数
DENSE_RANK() OVER(PARTITION dept_no ORDER BY salary DESC)可以得出以
部门为单位的员工的工资排名,可以满足并列第1的要求
SELECT D.dept_no,D.emp_no,D.salary
FROM(
SELECT
DENSE_RANK() OVER (PARTITION BY C.dept_no ORDER BY C.salary DESC) AS raking,
C.dept_no,
C.emp_no,
C.salary
FROM (
SELECT
A.dept_no,
A.emp_no,
B.salary
FROM
dept_emp A
INNER JOIN salaries B ON A.emp_no = B.emp_no
WHERE
A.to_date = '9999-01-01'
AND B.to_date = '9999-01-01'
) C
) D
WHERE D.raking = 1
ORDER BY D.dept_no
2、方法二:如果mysql数据库没有排序函数,则可以使用非等值自连接的方法来实现类似DENSE_RANK()
函数的功能,语句比较长,可以不过原理简单的,如下:
SELECT D.dept_no,D.emp_no,D.salary FROM(
SELECT (
SELECT COUNT( DISTINCT F.salary )
FROM(
SELECT
A.dept_no,
A.emp_no,
B.salary
FROM
dept_emp A
INNER JOIN salaries B ON A.emp_no = B.emp_no
WHERE
A.to_date = '9999-01-01'
AND B.to_date = '9999-01-01'
) AS F
WHERE
F.salary >= C.salary
AND F.dept_no = C.dept_no
) AS raking,
C.dept_no,C.emp_no,C.salary FROM (
SELECT
A.dept_no,
A.emp_no,
B.salary
FROM
dept_emp A
INNER JOIN salaries B ON A.emp_no = B.emp_no
WHERE
A.to_date = '9999-01-01'
AND B.to_date = '9999-01-01' ) C ) D
WHERE D.raking = 1
ORDER BY D.dept_no