按其他字段对值进行分组

时间:2018-02-09 08:34:57

标签: sql sql-server sql-server-2008 select aggregate

我有以下代码

ID | Name | Salary
---|------|-------
1  | Tom  | 100
2  | Tom  | 200
3  | Max  | 200
4  | Jim  | 100
5  | Max  |  50
6  | Tom  | 300
7  | Jim  | 200

我尝试从具有最高工资的用户名中获取这些ID。 预期结果:

ID | Name 
---|------
6  | Tom 
3  | Max 
7  | Jim 

我尝试过但没有成功:

SELECT ID, Name FROM Employee WHERE ID IN 
(
SELECT ID, FROM Employee GROUP BY Salary HAVING MAX(Salary)
)

2 个答案:

答案 0 :(得分:4)

解决此问题的一种方法是将Employee表加入子查询,该子查询标识每个名称的最高工资。

SELECT e1.ID, e1.Name
FROM Employee e1
INNER JOIN
(
    SELECT Name, MAX(Salary) AS max_salary
    FROM Employee
    GROUP BY Name
) e2
    ON e1.Name = e2.Name AND e1.Salary = e2.max_salary;

Demo

我们也可以使用相关子查询来解决这个问题:

SELECT e1.ID, e1.Name
FROM Employee e1
WHERE e1.Salary = (SELECT MAX(e2.Salary) FROM Employee e2
                   WHERE e1.Name = e2.Name);

为了完善这个答案,假设您正在使用SQL Server并且可以访问ROW_NUMBER,我们可以编写以下查询:

SELECT ID, Name
FROM
(
    SELECT ID, Name,
        ROW_NUMBER() OVER (PARTITION BY Name ORDER BY Salary DESC) rn
    FROM Employee
) t
WHERE rn = 1;

答案 1 :(得分:2)

您可以使用窗口功能轻松完成此操作:

select id, name, salary, 
from (
  select id, name, salary, 
         max(salary) over () as max_salary
  from employee
) t
where salary = max_salary
order by name;

您没有说明您的DBMS,但以上是标准SQL。这通常比使用额外group by

加入派生表更快