使用 GROUP BY 后查找具有 MAX 值的行

Posted

技术标签:

【中文标题】使用 GROUP BY 后查找具有 MAX 值的行【英文标题】:Finding rows with MAX value after using GROUP BY 【发布时间】:2020-12-23 02:26:11 【问题描述】:

我有一个有 4 列的表:dept_no, emp_no, from_date, to_date,其中每个 dept_noemp_no 是经理。

我想使用to_date 查找当前经理,我想显示dept_noemp_no

样本数据:

|emp_no  |dept_no  | from_date  |   to_date  |
| 11     | d001    | 1985-01-01 | 1991-10-01 |
| 12     | d001    | 1991-10-01 | 9999-01-01 |
| 21     | d002    | 1985-01-01 | 1989-12-17 |
| 22     | d002    | 1989-12-17 | 9999-01-01 |
| 31     | d003    | 1985-01-01 | 1992-03-21 |
| 32     | d003    | 1992-03-21 | 9999-01-01 |

样本输出:

|emp_no   |dept_no  |
|12       |d001     |
|22       |d002     |
|32       |d003     |

我想通了:

SELECT dept_no
     , emp_no 
  FROM 
     ( SELECT dept_no
            , MAX(to_date) as cur 
         FROM dept_manager 
        GROUP 
           BY dept_no) as new 
  JOIN dept_manager using(dept_no) 
 where cur = to_date;

我正在为每个部门查找MAX(to_date),然后在WHERE 子句中使用它。

这可行,但我觉得应该有更好的方法来做到这一点。

我见过很多类似的问题,但没有一个对我有帮助,因为我想显示一个不能在 group by 中使用的列。

【问题讨论】:

请分享一些示例数据和预期结果。您可以使用 row_number。 见meta.***.com/questions/333952/… mysql SQL Server。请仅标记一个数据库。 【参考方案1】:

一种可移植且通常有效的方法是使用子查询进行过滤:

select dept_no, emp_no
from dept_manager d
where to_date = (select max(d1.to_date) from dept_manager d1 where d1.dept_no = d.dept_no)

为了提高此查询的性能,您需要在(dept_no, to_date) 上建立索引。

另一种常见的方法是窗口函数:

select *
from (
    select d.*, row_number() over(partition by dept_no order by to_date desc) rn
    from dept_manager d
) d
where rn = 1

根据您的数据库和版本,可能会有更简洁的替代方案。

【讨论】:

使用子查询过滤有效,似乎是我想做的最佳方法。谢谢。

以上是关于使用 GROUP BY 后查找具有 MAX 值的行的主要内容,如果未能解决你的问题,请参考以下文章

从 GROUP BY 中获取具有 NULL 列的行

带有 MAX() 的 GROUP BY 返回错误的行 ID

BigQuery 和 GROUP BY 子句

使用 group_by 后根据条件转换哈希值

查找记录的属性是 GROUP BY 语句中某物的 MAX?

应用 group_by 并汇总数据,同时保留所有列的信息