我今天在Hacker News上发现了几个SQL tasks,但是我坚持要解决Postgres中的第二个任务,我将在这里描述:
您有以下简单的表结构:
列出各自部门薪水最高的员工。
我为你设置了一个SQL小提琴here。应该归还特里罗宾逊,劳拉怀特。除了他们的名字,它应该有他们的薪水和部门名称。
此外,我很想知道将返回Terry Robinsons(销售部门的最高薪水)和Laura White(营销部门的最高薪水)的查询以及IT部门的空行,以null
为员工;明确说明该部门没有雇员(因此没有薪水最高的人)。
答案 0 :(得分:5)
使用DISTINCT ON
进行更简单,更快速的查询,满足您的所有要求:
SELECT DISTINCT ON (d.id)
d.id AS department_id, d.name AS department
,e.id AS employee_id, e.name AS employee, e.salary
FROM departments d
LEFT JOIN employees e ON e.department_id = d.id
ORDER BY d.id, e.salary DESC;
->SQLfiddle(对于Postgres)。
另请注意LEFT [OUTER] JOIN
使部门在结果中没有员工。
每个部门只挑选one
名员工。如果有多个共享最高薪水,您可以添加更多ORDER BY项目以特别选择一个。否则,从同行中挑选出任意一个
如果没有员工,则仍会列出部门,其中员工列的值为NULL
。
您只需在SELECT
列表中添加所需的任何列。
在此相关答案中查找该技术的详细说明,链接和基准:
Select first row in each GROUP BY group?
除此之外:使用非描述性列名称(如name
或id
)是一种反模式。应为employee_id
,employee
等。
使用窗口函数rank()
(如@Scotch already posted,更简单,更快):
SELECT d.name AS department, e.employee, e.salary
FROM departments d
LEFT JOIN (
SELECT name AS employee, salary, department_id
,rank() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rnk
FROM employees e
) e ON e.department_id = d.department_id AND e.rnk = 1;
与您的示例(没有关系)的上述查询结果相同,只是稍微慢一些。
答案 1 :(得分:3)
这基本上就是你想要的。 Rank() Over
SELECT ename ,
departments.name
FROM ( SELECT ename ,
dname
FROM ( SELECT employees.name as ename ,
departments.name as dname ,
rank() over (
PARTITION BY employees.department_id
ORDER BY employees.salary DESC
)
FROM Employees
JOIN Departments on employees.department_id = departments.id
) t
WHERE rank = 1
) s
RIGHT JOIN departments on s.dname = departments.name
答案 2 :(得分:2)
这是关于你的小提琴:
SELECT * -- or whatever is your columns list.
FROM employees e JOIN departments d ON e.Department_ID = d.id
WHERE (e.Department_ID, e.Salary) IN (SELECT Department_ID, MAX(Salary)
FROM employees
GROUP BY Department_ID)
编辑:
如下面的评论所述,如果您想要查看IT部门,并且员工记录的所有NULL
都可以使用RIGHT JOIN
并将过滤条件放入加入条款中本身如下:
SELECT e.name, e.salary, d.name -- or whatever is your columns list.
FROM employees e RIGHT JOIN departments d ON e.Department_ID = d.id
AND (e.Department_ID, e.Salary) IN (SELECT Department_ID, MAX(Salary)
FROM employees
GROUP BY Department_ID)
答案 3 :(得分:2)
为薪水最高的每个部门返回一个或多个人:
SELECT result.Name Department, Employee2.Name Employee, result.salary Salary
FROM ( SELECT dept.name, dept.department_id, max(Employee1.salary) salary
FROM Departments dept
JOIN Employees Employee1 ON Employee1.department_id = dept.department_id
GROUP BY dept.name, dept.department_id ) result
JOIN Employees Employee2 ON Employee2.department_id = result.department_id
WHERE Employee2.salary = result.salary
答案 4 :(得分:0)
好古老的经典sql:
select e1.name, e1.salary, e1.department_id
from employees e1
where e1.salary=
(select maxsalary=max(e.salary) --, e. department_id
from employees e
where e.department_id = e1.department_id
group by e.department_id
)
答案 5 :(得分:0)
表1是emp - empno,ename,sal,deptno
表2是dept - deptno,dname。
select e1.empno, e1.ename, e1.sal, e1.deptno as department
from emp e1
where e1.sal in
(SELECT max(sal) from emp e, dept d where e.deptno = d.deptno group by d.dname)
order by e1.deptno asc;
答案 6 :(得分:0)
SELECT
e.first_name, d.department_name, e.salary
FROM
employees e
JOIN
departments d
ON
(e.department_id = d.department_id)
WHERE
e.first_name
IN
(SELECT TOP 2
first_name
FROM
employees
WHERE
department_id = d.department_id);
答案 7 :(得分:0)
`select d.Name, e.Name, e.Salary from Employees e, Departments d,
(select DepartmentId as DeptId, max(Salary) as Salary
from Employees e
group by DepartmentId) m
where m.Salary = e.Salary
and m.DeptId = e.DepartmentId
and e.DepartmentId = d.DepartmentId`
使用GROUP BY在内部查询中计算每个部门的最高工资。然后选择满足这些约束条件的员工。
答案 8 :(得分:0)
假设Postgres
返回员工详细信息的最高薪水,假设表名为emp且员工部门为dept_id
df1 = df[((df['category'] == 'A') & (df['value'].between(10,20))) |
(df['category'] != 'A')]
print (df1)
category value
1 B 10
2 A 15
3 B 28
4 A 18
答案 9 :(得分:0)
SQL查询:
select d.name,e.name,e.salary
from employees e, depts d
where e.dept_id = d.id
and (d.id,e.salary) in
(select dept_id,max(salary) from employees group by dept_id);
答案 10 :(得分:-1)
看看这个解决方案 选择 MAX(E.SALARY) E.NAME, D.NAME作为部门 来自员工E. 内部联合部门D ON D.ID = E.DEPARTMENT_ID GROUP BY D.NAME