4

我今天在 Hacker News 上发现了几个 SQL任务,但是我一直在解决 Postgres 中的第二个任务,我将在这里描述:

您有以下简单的表结构:

在此处输入图像描述

列出各自部门薪水最高的员工。

我在这里设置了一个 SQL Fiddle供您使用。它应该返回特里罗宾逊,劳拉怀特。除了他们的名字,它还应该有他们的薪水和部门名称。

此外,我很想知道一个查询会返回 Terry Robinsons(销售部门的最高薪水)和 Laura White(营销部门的最高薪水)以及 IT 部门的空行,null作为员工;明确说明该部门没有员工(因此没有人薪水最高)。

4

11 回答 11

6

返回每个部门工资最高的一名员工。

用于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

在此相关答案中找到该技术的详细解释、链接和基准:
选择每个 GROUP BY 组中的第一行?

旁白:使用非描述性的列名(如nameor )是一种反模式id。应该是employee_idemployee

返回每个部门工资最高的所有员工。

使用窗口函数rank()(就像@Scotch 已经发布的一样,更简单、更快):

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;

与您的示例(没有联系)的上述查询相同的结果,只是慢了一点。

于 2013-05-28T22:37:27.960 回答
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
于 2013-05-28T19:16:24.143 回答
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 JOINand 将过滤条件放在加入子句本身中,如下所示:

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)
于 2013-05-28T19:16:04.137 回答
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);
于 2014-09-09T13:42:34.130 回答
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
   )
于 2014-03-28T20:37:26.177 回答
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 计算。然后选择满足这些限制的员工。

于 2015-02-27T03:29:14.693 回答
0

表 1 是 emp - empno、ename、sal、deptno

表 2 是 dept - deptno, dname。

查询可能是(包括 11.2g 上的关系和运行):

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; 
于 2014-04-10T04:11:28.427 回答
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);
于 2019-11-06T21:59:04.487 回答
0

假设 Postgres

返回带有员工详细信息的最高薪水,假设表名 emp 的员工部门为 dept_id

select e1.* from emp e1  inner join (select max(sal) avg_sal,dept_id from emp group by dept_id) as e2 on e1.dept_id=e2.dept_id and e1.sal=e2.avg_sal
于 2017-04-26T11:31:10.227 回答
0

返回每个部门工资最高的一个或多个人:

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
于 2018-06-18T05:26:33.960 回答
-1

看看这个解决方案 SELECT MAX(E.SALARY), E.NAME, D.NAME as Department FROM employees E INNER JOIN DEPARTMENTS D ON D.ID = E.DEPARTMENT_ID GROUP BY D.NAME

于 2013-05-28T19:40:34.307 回答