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

问题描述

我有一个包含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子句中使用它。

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

我看到了许多类似的问题,但是没有一个问题帮助我,因为我想显示不能在分组依据中使用的列。

解决方法

一种便携式且通常有效的方法是使用子查询进行过滤:

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

根据您的数据库和版本,可能会有更整齐的选择。