查找每个部门的最高薪水 - 是不是有更有效的查询?

Posted

技术标签:

【中文标题】查找每个部门的最高薪水 - 是不是有更有效的查询?【英文标题】:Find top salary per department - is there a more efficient query?查找每个部门的最高薪水 - 是否有更有效的查询? 【发布时间】:2019-10-03 06:50:11 【问题描述】:

我有一个有效的查询,但我怀疑我这样做效率低下。有没有更优雅的方法来查找每个部门的最高薪水以及获得最高薪水的员工?

我正在做一个 cte 来查找每个部门 ID 的最高工资,然后通过匹配工资和部门 ID 将其与员工数据连接起来。我有下面的代码来构建/填充表格和最后的查询。

CREATE TABLE employee (
emplid SERIAL PRIMARY KEY,
name VARCHAR NOT NULL,
salary FLOAT NOT NULL,
depid INTEGER
);

INSERT INTO employee (name, salary, depid)
VALUES
('Chris',23456.99,1),
('Bob',98756.34,1),
('Malin',34567.22,2),
('Lisa',34967.73,2),
('Deepak',88582.22,3),
('Chester',99487.41,3);

CREATE TABLE department (
depid SERIAL PRIMARY KEY,
deptname VARCHAR NOT NULL
);

INSERT INTO department (deptname)
VALUES
('Engineering'),
('Sales'),
('Marketing');

--top salary by department
WITH cte AS (
SELECT d.depid, deptname, MAX(salary) AS maxsal
FROM employee e
JOIN department d ON d.depid = e.depid
GROUP BY d.depid, deptname
)
SELECT cte.deptname, e.name, cte.maxsal
FROM cte
JOIN employee e ON cte.depid = e.depid
AND e.salary = cte.maxsal
ORDER BY maxsal DESC;

这是目标结果:

“营销”“切斯特”“99487.41” “工程”“鲍勃”“98756.34” “销售”“丽莎”“34967.73”

【问题讨论】:

相关:Why not use Double or Float to represent currency? 【参考方案1】:

你应该有一个索引:

create index employee_depid_salary_desc_idx on employee(depid, salary desc);

然后使用以下可以使用索引的查询:

select
  depid,
  deptname,
  (
    select
      emplid
    from employees
    where depid=department.depid
    order by salary desc
    limit 1
  ) as max_salaried_emplid
from department;

(用于从左侧检索数据的连接作为读者练习)。

【讨论】:

警告:如果一个部门内有 2 名或更多员工的最高薪水,上述查询将检索其中一名,但未定义是哪一名。【参考方案2】:

在 Postgres 中,这可以使用 distinct on () 运算符解决:

SELECT distinct on (d.depid) d.depid, deptname, e.name, e.salary AS maxsal
FROM employee e
  JOIN department d ON d.depid = e.depid
order by d.depid, e.salary desc;

或者你可以使用窗口函数:

select depid, deptname, emp_name, salary
from (
  SELECT d.depid, 
         deptname, 
         e.name as emp_name, 
         e.salary, 
         max(e.salary) over (partition by d.depid) AS maxsal
  FROM employee e
    JOIN department d ON d.depid = e.depid
) t
where salary = maxsal;

在线示例:https://rextester.com/MBAF73582

【讨论】:

以上是关于查找每个部门的最高薪水 - 是不是有更有效的查询?的主要内容,如果未能解决你的问题,请参考以下文章

Mysql案例4:要求查询平均薪水最高部门的部门编号

如何使用 SUBQUERIES 找到每个部门的最高薪水

牛客网专题SQL206 获取每个部门中当前员工薪水最高的相关信息

SQL查询查找每种语言的最高薪水

Mysql 练习题10道(1-10题)

从单独的表中获取最高薪水获取者及其部门