使用MAX()和GROUP BY

时间:2014-03-21 13:17:48

标签: sql-server

我有一张历史记录表,我想获得一名员工的最新修改。 我有这个例子,max总是带来一条记录?

 CREATE TABLE EmployeeHIST
 (
 Id INT PRIMARY KEY,
 EmployeeId INT,
 FirstName NVARCHAR(50),
 LastName NVARCHAR(50),
 ModifiedDate DATETIME
 )

 INSERT INTO EmployeeHIST VALUES (1, 1, 'Jhon', 'Doo', '2013-01-24 23:45:12')
 INSERT INTO EmployeeHIST VALUES (2, 1, 'Jhon', 'Doo', '2013-02-24 15:45:12')
 INSERT INTO EmployeeHIST VALUES (3, 1, 'Jhon', 'Doo', '2013-02-24 15:45:12')

SELECT EmployeeId, MAX([ModifiedDate])
FROM EmployeeHIST
WHERE EmployeeId = 1
GROUP BY EmployeeId

好的是,你是对的,但是如果我需要获得EmployeeId = 1的Id列,在这种情况下我将收到两个值2和3,所以我需要应用一个顶部的权利吗?

1 个答案:

答案 0 :(得分:1)

Max()为分组依据中定义的每个值组合带来一条记录。

在您的示例数据中,是的始终是一条记录。

如果您是Group By Id,EmployeeId,您将获得三条记录,因为这些值有三种独特的组合。

这也适用于其他聚合功能 Min() Avg() Count()

<强>更新 如果你想获得具有max(日期)的记录的id,那么你有以下选项(可能有更好的选项):

;With MyCTE AS
(
    SELECT EmployeeId, MAX([ModifiedDate]) AS MaxDate
    FROM EmployeeHIST
    GROUP BY EmployeeId
)
SELECT E.Id,E.EmployeeId,ModifiedDate
FROM   EmployeeHIST E
       JOIN MyCTE M
           ON M.EmployeeId = E.EmployeeId
           AND M.MaxDate = E.ModifiedDate
WHERE  E.EmployeeId = 1

<强> SQLFiddle 1

现在,在这种情况下,您返回了ID 2和3。我不知道这里的业务需求是什么,但我相信你只想要返回3,所以下一个是解决方案:

;With MyCTE AS
(
    SELECT EmployeeId, MAX([ModifiedDate]) AS MaxDate
    FROM EmployeeHIST
    GROUP BY EmployeeId
)
SELECT MAX(E.Id),E.EmployeeId,ModifiedDate
FROM   EmployeeHIST E
       JOIN MyCTE M
           ON M.EmployeeId = E.EmployeeId
           AND M.MaxDate = E.ModifiedDate
WHERE  E.EmployeeId = 1
GROUP BY E.EmployeeId,ModifiedDate

<强> SQLFiddle 2