groupby 结果的 sql in 子句

问题描述 投票:0回答:2

给了一个桌子员工


Employee
id  name    salary  departmentid
1   joe 70000   1
2   jim 90000   1
3   henry   80000   2
5   max 90000   1

我应用了一个简单的查询

SELECT name, Salary
FROM Employee
WHERE (DepartmentId, Salary) IN (SELECT DepartmentId, MAX(Salary)
                                 FROM Employee
                                 GROUP BY DepartmentId);

输出如下

name    salary
jim 90000
henry   80000
max 90000

我期待着吉姆或马克斯·罗之一。对于 Departmentid 1,两者的工资都是 90000,所以 max(salary) 会选择其中之一,如下面的查询所示,但我同时得到 max 和 jim。子查询的结果

SELECT name,DepartmentId, MAX(Salary) FROM Employee GROUP BY DepartmentId 
name    departmentid    MAX(Salary)
jim 1           90000
henry   2           80000

它只给出 jim 而不是 max。你能解释一下第一个查询如何给出 3 个结果,而下面的查询只给出两个结果吗?我们将非常感谢您的意见。

sql aggregate
2个回答
0
投票

第一个查询

SELECT name, Salary
FROM Employee
WHERE (DepartmentId , Salary) IN (
    SELECT DepartmentId, MAX(Salary)
    FROM Employee
    GROUP BY DepartmentId ) ;

要求:

  • 表中的所有行
  • 与...的
    DepartmentId, Salary
    匹配子查询
    • 表格中的所有行
    • DepartmentId
    • 分组
    • 并聚合最大
      Salary

因此,有必要包括所有并列结果,因为它包括与 Salary 匹配的

all
行。


第二个查询使用了 MySQL 允许非分组列的错误功能。它本质上与使用非确定性

ANY
相同。

SELECT
  ANY(name),
  DepartmentId,
  MAX(Salary)
FROM Employee
GROUP BY DepartmentId 

所以每个

DepartmentId
只能得到一行。


这些查询都不是很好。理想情况下,您应该使用窗口函数来解决每组前 n 个问题。

SELECT
  e.name,
  e.DepartmentId,
  e.Salary
FROM (
    SELECT *,
      ROW_NUMBER() OVER (PARTITION BY e.DepartmentId ORDER BY e.Salary DESC) AS rn
    FROM Employee e
) e
WHERE e.rn = 1;

如果您仍然想要平局结果,请将

ROW_NUMBER
更改为
DENSE_RANK


0
投票

第一个查询只检索满足where条件的。如果可以的话,你有两个名字满足departmentId = 1和max(salary) = 90000。

第二个查询只带来第一次出现的情况,而不是全部。

© www.soinside.com 2019 - 2024. All rights reserved.