有一个员工表dept_emp简况如下: emp_no dept_no from_date to_date 10001 d001 1986-06-26 9999-01-01 10002 d001 1996-08-03 9999-01-01 10003 d002 1996-08-03 9999-01-01 有一个薪水表salaries简况如下: emp_no salary from_date to_date 10001 88958 2002-06-22 9999-01-01 10002 72527 2001-08-02 9999-01-01 10003 92527 2001-08-02 9999-01-01 获取每个部门中当前员工 薪水最高的相关信息,给出dept_no, emp_no以及其对应的salary, 按照部门编号dept_no升序排列,以上例子输出如下: dept_no emp_no maxSalary d001 10001 88958 d002 10003 92527
区块链毕设网qklbishe.com为您提供问题的解答
emp_no | dept_no | from_date | to_date |
10001 | d001 | 1986-06-26 | 9999-01-01 |
10002 | d001 | 1996-08-03 | 9999-01-01 |
10003 | d002 | 1996-08-03 | 9999-01-01 |
emp_no | salary | from_date | to_date |
10001 | 88958 | 2002-06-22 | 9999-01-01 |
10002 | 72527 | 2001-08-02 | 9999-01-01 |
10003 | 92527 | 2001-08-02 | 9999-01-01 |
dept_no | emp_no | maxSalary |
d001 | 10001 | 88958 |
d002 | 10003 | 92527 |
(dept_no,salary) in (select dept_no,max(salary) ……)
完整代码如下:
select dept_no,s.emp_no,salary maxSalary from dept_emp de join salaries s on de.emp_no=s.emp_no where (dept_no,salary) in (select dept_no,max(salary) from dept_emp de join salaries s on de.emp_no=s.emp_no where s.to_date='9999-01-01' and de.to_date='9999-01-01' group by dept_no) order by dept_no
#主要问题:通过常规的聚合函数获取salary时,无法正确获取对应的员工编号。 #方法1:使用两张表,写的比较冗长,但是更加直观(吧...)。先获取员工当前薪资表,再获取部门最高薪资表。 #然后用薪资作为筛选条件对应以获取正确的员工编号。 # SELECT t2.dept_no, t1.emp_no, t2.max_salary # FROM # ( # SELECT e.emp_no , e.dept_no , s.salary # FROM dept_emp e # JOIN salaries s # ON e.emp_no=s.emp_no # AND e.to_date='9999-01-01' # AND s.to_date='9999-01-01' # ) t1 # JOIN # ( # SELECT e.dept_no , MAX(salary) max_salary # FROM dept_emp e # JOIN salaries s # ON e.emp_no=s.emp_no # AND e.to_date='9999-01-01' # AND s.to_date='9999-01-01' # GROUP BY e.dept_no # ) t2 # ON t1.dept_no=t2.dept_no # WHERE t1.salary=t2.max_salary # ORDER BY t2.dept_no #方法2:使用窗口函数。本质就是根据部门划分窗口,对每个部门的员工和薪资记录增加独立排序。 #因此只要获取每个部门排名第一的记录就可以了 SELECT t.dept_no, t.emp_no, t.salary FROM ( SELECT d.dept_no, d.emp_no, s.salary, RANK() OVER(PARTITION BY d.dept_no ORDER BY s.salary DESC) dept_s_ranking FROM dept_emp d JOIN salaries s ON d.emp_no=s.emp_no AND d.to_date='9999-01-01' AND s.to_date='9999-01-01' )t WHERE t.dept_s_ranking=1;
select de.dept_no, de.emp_no, s.salary
from dept_emp de inner join salaries s
on de.emp_no = s.emp_no
and de.to_date = ‘9999-01-01’
and s.to_date = ‘9999-01-01’
where s.salary = (select max(s2.salary)
from dept_emp de2 inner join salaries s2
on de2.emp_no = s2.emp_no
and de2.to_date = ‘9999-01-01’
and s2.to_date = ‘9999-01-01’
where de2.dept_no = de.dept_no
group by de2.dept_no)
SELECT d.dept_no, s.emp_no, MAX(s.salary) AS salary FROM salaries AS s INNER JOIN dept_emp As d 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
SELECT currentsalary.dept_no, currentsalary.emp_no, currentsalary.salary AS salary FROM //创建maxsalary表用于存放当前每个部门薪水的最大值 (SELECT d.dept_no, MAX(s.salary) AS salary FROM salaries AS s INNER JOIN dept_emp As d 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) AS maxsalary, //创建currentsalary表用于存放当前每个部门所有员工的编号和薪水 (SELECT d.dept_no, s.emp_no, s.salary FROM salaries AS s INNER JOIN dept_emp As d ON d.emp_no = s.emp_no WHERE d.to_date = '9999-01-01' AND s.to_date = '9999-01-01' ) AS currentsalary //限定条件为两表的dept_no和salary均相等 WHERE currentsalary.dept_no = maxsalary.dept_no AND currentsalary.salary = maxsalary.salary //最后以currentsalary.dept_no排序输出符合要求的记录表 ORDER BY currentsalary.dept_no
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、方法一:使用窗口排序函数 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
【注】DENSE_RANK() OVER(PARTITION dept_no ORDER BY salary DESC)可以得出以 部门为单位的员工的工资排名,可以满足并列第1的要求 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
where A.to_date=’9999-01-01′ and B.to_date=’9999-01-01′
GROUP BY B.dept_no
having A.salary=max(A.salary);
where A.to_date=’9999-01-01′ and B.to_date=’9999-01-01′
GROUP BY B.dept_no;
它的结果是:
SELECT D.dept_no AS dept_no,S.emp_no AS emp_no,S.salary AS salary from salaries AS S JOIN dept_emp as D on S.emp_no=D.emp_no
where D.to_date=’9999-01-01′ and S.to_date=’9999-01-01′
ORDER BY salary DESC
) as b
GROUP BY dept_no
先进行降序排序,再分组,结果却是
--评论区的一些答案没有把GROUP BY 默认取非聚合的第一条记录考虑进去 --以下是我的答案: SELECT r1.dept_no, r1.emp_no, r1.salary FROM --创建r1表用于存放当前每个部门每个员工的薪水 ( SELECT d.dept_no, d.emp_no, s1.salary FROM dept_emp d, salaries s1 WHERE d.to_date='9999-01-01' AND s1.to_date='9999-01-01' AND d.emp_no = s1.emp_no)r1 JOIN --创建r2表用于存放当前每个部门薪水的最大值 ( SELECT d.dept_no, MAX(s2.salary) as maxsalary FROM dept_emp d --为了避免GROUP BY默认取非聚合数据的第一条记录,先把salary排好序 JOIN (SELECT * FROM salaries ORDER BY salary DESC)s2 ON d.emp_no = s2.emp_no WHERE d.to_date='9999-01-01' AND s2.to_date='9999-01-01' GROUP BY d.dept_no)r2 ON r1.salary = r2.maxsalary AND r1.dept_no = r2.dept_no ORDER BY r2.dept_no
解法一 纯 JOIN
select t.dept_no, j.emp_no, t.maxSalary from ( select d.dept_no as dept_no, max(s.salary) as maxSalary from dept_emp d join salaries s on s.emp_no = d.emp_no group by d.dept_no ) as t inner join ( select d.dept_no as dept_no, s.salary as salary, d.emp_no as emp_no from dept_emp d join salaries s on s.emp_no = d.emp_no ) as j on j.dept_no = t.dept_no and j.salary = t.maxSalary order by t.dept_no asc;
第一个子查询先聚合,group by 聚合键 和 聚合函数 求出每个部门和它的最高薪水,问题在于没有emp_no,接下来我们补充这个字段。
第二个子查询 join 两张表,得到一张宽表,通过dept_no和salary定位到emp_no。
解法二
select t.dept_no, s.emp_no, t.maxSalary from ( select d.dept_no, max(s.salary) as maxSalary from dept_emp d,salaries s where d.emp_no = s.emp_no group by d.dept_no ) as t, salaries s, dept_emp d where t.maxSalary = s.salary and t.dept_no = d.dept_no and d.emp_no = s.emp_no order by t.dept_no asc
在子查询里面找到 dept_no 和 maxSalary,外部用 where 条件限定,最后按照部门排序。
解法三 利用 MYSQL 8.0 之后的开窗函数
select dept_no, emp_no, maxSalary from ( select d.dept_no as dept_no,d.emp_no as emp_no,s.salary as salary, first_value(salary) over(partition by d.dept_no order by s.salary desc) as maxSalary from dept_emp d join salaries s on s.emp_no = d.emp_no ) as t where salary = maxSalary
运行时间 52ms
占用内存 6776KB
按照部门分区,再按照薪水倒序排序,取第一条就是最大薪资
first_value(salary) over(partition by d.dept_no order by s.salary desc) as maxSalary
where salary = maxSalary
利用 rank() :
select dept_no, emp_no,salary as maxSalary from ( select d.dept_no as dept_no, d.emp_no as emp_no, s.salary as salary, rank() over(partition by d.dept_no order by s.salary desc) as ranking from dept_emp d join salaries s on s.emp_no = d.emp_no ) as t where t.ranking = 1;
SELECT a.dept_no, a.emp_no, a.salary AS maxSalary FROM (SELECT d.emp_no, d.dept_no, s.salary, DENSE_RANK() OVER (PARTITION BY d.dept_no ORDER BY s.salary DESC) AS rk FROM dept_emp AS d INNER JOIN salaries AS s ON d.emp_no = s.emp_no AND d.to_date = '9999-01-01' AND s.to_date = '9999-01-01' )AS a WHERE a.rk = 1 ORDER BY a.dept_no;
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’
GROUP BY
d.dept_no
HAVING
s.salary = max(s.salary);
d.dept_no,
d.emp_no,
max(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’
GROUP BY
d.dept_no;
re1.dept_no,
re2.emp_no,
re1.salary
FROM
(
SELECT
dept_em.dept_no,
max(em_sa.salary) salary
FROM
(
(
SELECT
emp_no,
salary
FROM
salaries
WHERE
to_date = ‘9999-01-01’
) em_sa
LEFT JOIN (
SELECT
emp_no,
dept_no
FROM
dept_emp
WHERE
to_date = ‘9999-01-01’
) dept_em ON em_sa.emp_no = dept_em.emp_no
)
GROUP BY
dept_no
) re1
JOIN (
SELECT
dept_em.dept_no,
em_sa.emp_no,
em_sa.salary salary
FROM
(
(
SELECT
emp_no,
salary
FROM
salaries
WHERE
to_date = ‘9999-01-01’
) em_sa
LEFT JOIN (
SELECT
emp_no,
dept_no
FROM
dept_emp
WHERE
to_date = ‘9999-01-01’
) dept_em ON em_sa.emp_no = dept_em.emp_no
)
) re2 ON re1.dept_no = re2.dept_no
AND re1.salary = re2.salary
ORDER BY
re1.dept_no;
(SELECT
d.dept_no,
max(s.salary) as maxSalary
FROM
dept_emp d,
salaries s
WHERE
d.emp_no = s.emp_no
GROUP BY
d.dept_no) t where de.dept_no = t.dept_no and de.emp_no = sal.emp_no and sal.salary = t.maxSalary AND de.to_date = ‘9999-01-01′ and sal.to_date =’9999-01-01’ ORDER BY de.dept_no;
个人认为这个是最严谨最正确的写法
1.按照emp_no连接两个表
2.注意时间 需要是当前 两边表的date都要是99990101
3.group by部门号dept_no 添加条件工资=最高工资
SELECT e.dept_no, e.emp_no, s.salary FROM dept_emp AS e INNER JOIN salaries AS s ON e.emp_no = s.emp_no WHERE e.to_date = '9999-01-01' AND s.to_date = '9999-01-01' GROUP BY e.dept_no HAVING s.salary = MAX(s.salary);
(select d.dept_no,d.emp_no,s.salary,
rank() over(partition by d.dept_no order by s.salary desc) rn
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′)
a where rn=1
这道题目的判题系统有问题, 很多人都回答错误了, 但是通过了判题系统
下面是真`正确答案的写法:
写法一:
select dept_emp.dept_no as dept_no_a, dept_emp.emp_no, max(salaries.salary) as salary from dept_emp,salaries where salaries.emp_no=dept_emp.emp_no group by dept_emp.emp_no,dept_emp.dept_no having max(salaries.salary) = ( select max(salaries.salary) from dept_emp inner join salaries on salaries.emp_no=dept_emp.emp_no where dept_emp.dept_no = dept_no_a ) order by dept_no_a
写法二:
select distinct dept_no, s.emp_no, salary from dept_emp as d inner join salaries as s on s.emp_no = d.emp_no and s.salary = (select s2.salary from salaries as s2 inner join dept_emp as d2 on s2.emp_no = d2.emp_no where d2.dept_no = d.dept_no order by s2.salary desc limit 1 ) order by dept_no ;
写法三:
受限于any_value的实现,如果是返回第一个值就没有问题
select ret.dept_no, any_value(ret.emp_no), max(ret.salary) from (select dept_emp.dept_no,dept_emp.emp_no, max(salaries.salary) as salary from dept_emp,salaries where salaries.emp_no=dept_emp.emp_no group by dept_emp.emp_no,dept_emp.dept_no order by salary desc ) as ret group by ret.dept_no
# 开窗函数,分组排序后取每组第一行 SELECT dept_no, emp_no, salary maxSalary FROM (SELECT dept.dept_no, dept.emp_no, sal.salary, DENSE_RANK() over (partition by dept_no order by salary desc) as rownum FROM dept_emp dept LEFT JOIN salaries sal ON dept.emp_no = sal.emp_no) tmp WHERE rownum = 1 ORDER BY dept_no
错误总结:1).groupby子句常见错误
SELECT 子句中只能存在以下三种元素。
● 常数 ● 聚合函数 ● GROUP BY子句中指定的列名(也就是聚合键)
#错误用法 SELECT product_name, purchase_price, COUNT(*) -- 列名product_name不能包含 FROM Product GROUP BY purchase_price;
2).同一部门存在多个拿最高薪的员工, 怎么办?
代码:
select T1.dept_no,T2.emp_no,T1.maxSalary from ( select de.dept_no,max(salary) as maxSalary from dept_emp de join salaries sa on de.emp_no=sa.emp_no group by dept_no )as T1 join ( select de.dept_no,sa.salary,sa.emp_no from dept_emp de join salaries sa on de.emp_no=sa.emp_no )as T2 on T1.maxSalary =T2.salary and T1.dept_no=T2.dept_no order by dept_no
from
(select d.dept_no,max(salary) max_salary
from dept_emp d,salaries s
where d.emp_no=s.emp_no and s.to_date=’9999-01-01′ and d.to_date=’9999-01-01′
group by dept_no) as X,
from dept_emp d,salaries s
where d.emp_no=s.emp_no and s.to_date=’9999-01-01′ and d.to_date=’9999-01-01′) as Y
以上就是关于问题有一个员工表dept_emp简况如下: emp_no
dept_no
from_date
to_date
10001 d001
1986-06-26 9999-01-01
10002 d001
1996-08-03 9999-01-01 10003 d002
1996-08-03 9999-01-01
有一个薪水表salaries简况如下: emp_no
salary
from_date
to_date 10001
88958 2002-06-22
9999-01-01 10002
72527 2001-08-02
9999-01-01
10003
92527 2001-08-02 9999-01-01
获取每个部门中当前员工 薪水最高的相关信息,给出dept_no, emp_no以及其对应的salary, 按照部门编号dept_no升序排列,以上例子输出如下: dept_no
emp_no
maxSalary
d001 10001
88958 d002 10003
92527的答案
欢迎关注区块链毕设网-
专业区块链毕业设计成品源码,定制。
区块链NFT链游项目方科学家脚本开发培训
从业7年-专注一级市场
微信:btc9767
TELEGRAM :https://t.me/btcok9
具体资料介绍
web3的一级市场千万收益的逻辑
进群点我
qklbishe.com区块链毕设代做网专注|以太坊fabric-计算机|java|毕业设计|代做平台-javagopython毕设 » 有一个员工表dept_emp简况如下: emp_no
dept_no
from_date
to_date
10001 d001
1986-06-26 9999-01-01
10002 d001
1996-08-03 9999-01-01 10003 d002
1996-08-03 9999-01-01
有一个薪水表salaries简况如下: emp_no
salary
from_date
to_date 10001
88958 2002-06-22
9999-01-01 10002
72527 2001-08-02
9999-01-01
10003
92527 2001-08-02 9999-01-01
获取每个部门中当前员工 薪水最高的相关信息,给出dept_no, emp_no以及其对应的salary, 按照部门编号dept_no升序排列,以上例子输出如下: dept_no
emp_no
maxSalary
d001 10001
88958 d002 10003
92527
微信:btc9767
TELEGRAM :https://t.me/btcok9
具体资料介绍
web3的一级市场千万收益的逻辑
进群点我
qklbishe.com区块链毕设代做网专注|以太坊fabric-计算机|java|毕业设计|代做平台-javagopython毕设 » 有一个员工表dept_emp简况如下: emp_no
dept_no
from_date
to_date
10001 d001
1986-06-26 9999-01-01
10002 d001
1996-08-03 9999-01-01 10003 d002
1996-08-03 9999-01-01
有一个薪水表salaries简况如下: emp_no
salary
from_date
to_date 10001
88958 2002-06-22
9999-01-01 10002
72527 2001-08-02
9999-01-01
10003
92527 2001-08-02 9999-01-01
获取每个部门中当前员工 薪水最高的相关信息,给出dept_no, emp_no以及其对应的salary, 按照部门编号dept_no升序排列,以上例子输出如下: dept_no
emp_no
maxSalary
d001 10001
88958 d002 10003
92527
进群点我
qklbishe.com区块链毕设代做网专注|以太坊fabric-计算机|java|毕业设计|代做平台-javagopython毕设 » 有一个员工表dept_emp简况如下: emp_no
dept_no
from_date
to_date
10001 d001
1986-06-26 9999-01-01
10002 d001
1996-08-03 9999-01-01 10003 d002
1996-08-03 9999-01-01
有一个薪水表salaries简况如下: emp_no
salary
from_date
to_date 10001
88958 2002-06-22
9999-01-01 10002
72527 2001-08-02
9999-01-01
10003
92527 2001-08-02 9999-01-01
获取每个部门中当前员工 薪水最高的相关信息,给出dept_no, emp_no以及其对应的salary, 按照部门编号dept_no升序排列,以上例子输出如下: dept_no
emp_no
maxSalary
d001 10001
88958 d002 10003
92527
qklbishe.com区块链毕设代做网专注|以太坊fabric-计算机|java|毕业设计|代做平台-javagopython毕设 » 有一个员工表dept_emp简况如下: emp_no dept_no from_date to_date 10001 d001 1986-06-26 9999-01-01 10002 d001 1996-08-03 9999-01-01 10003 d002 1996-08-03 9999-01-01 有一个薪水表salaries简况如下: emp_no salary from_date to_date 10001 88958 2002-06-22 9999-01-01 10002 72527 2001-08-02 9999-01-01 10003 92527 2001-08-02 9999-01-01 获取每个部门中当前员工 薪水最高的相关信息,给出dept_no, emp_no以及其对应的salary, 按照部门编号dept_no升序排列,以上例子输出如下: dept_no emp_no maxSalary d001 10001 88958 d002 10003 92527