SQL如何按

时间:2015-04-28 19:53:32

标签: sql sql-server

我有一个像这样的表结构:

UserID  | Firstname | LastName | DateTime
-------------------------------------------
1       | John      | Doe      | 2015-04-27
2       | Karl      | Watts    | 2015-04-26
1       | John      | Doe      | 2015-04-25
3       | Jane      | Howard   | 2015-04-28

有没有办法可以编写查询来获取DateTime排序的数据,但是按UserID分组?我希望记录的最新DateTime位于顶部,其余的用户记录将遵循。然后它应该是具有最新日期的下一个用户,然后是所有记录。像这样:

UserID  | Firstname | LastName | DateTime
-------------------------------------------
3       | Jane      | Howard   | 2015-04-28
1       | John      | Doe      | 2015-04-27
1       | John      | Doe      | 2015-04-25
2       | Karl      | Watts    | 2015-04-26

我只是不知道单个查询是否可以实现这一点。到目前为止,我已经提出了这个问题:

SELECT UserID, FirstName, LastName, MAX(DateTime) as MaxDateTime
FROM Table
GROUP BY UserID, FirstName, LastName
ORDER BY MaxDateTime DESC

以正确的顺序给出了最新的记录,但我不知道如何为每个用户包含剩余的记录。我认为我需要使用连接,但是当我这样做时,该组将所有组合在一起(应该如此)。

编辑: 是的,它需要正常化。 2.它是SQL Server 2008 R2,我确认OVER适用于2008及更高版本,因此非常完美。 3.如果是平局,则较低的UserID首先工作。

谢谢!

2 个答案:

答案 0 :(得分:3)

您可以将OVER()与聚合一起使用,无需对所有字段进行分组即可获得汇总:

SELECT UserID
     , FirstName
     , LastName
     , DateTime
     , MAX(DateTime) OVER(PARTITION BY UserID) as MaxDateTime
FROM Table
ORDER BY MaxDateTime DESC,UserID,DateTime DESC

如果您不想退回ORDER BY,可以将其限制为MaxDateTime

SELECT UserID
     , FirstName
     , LastName
     , DateTime         
FROM Table
ORDER BY MAX(DateTime) OVER(PARTITION BY UserID) DESC, UserID,DateTime DESC

演示:SQL Fiddle

编辑:请注意,如果出现平局,这将首先返回较低的UserID

答案 1 :(得分:1)

这将提供结果,根据MAX(DateTime)排序,并按关联情况按升序排序UserID。输出以DateTime的降序显示每个用户的行。

SELECT
    MaxT.UserID,
    T.FirstName,
    T.LastName,
    T.DateTime
FROM
    (
    SELECT
        UserID,
        MAX(DateTime) AS MaxDateTime
    FROM
        MyTable
    GROUP BY
        UserID
    ) AS MaxT
    INNER JOIN MyTable AS T ON
        T.UserID = MaxT.UserID
ORDER BY
    MaxT.MaxDateTime DESC,
    MaxT.UserID ASC,
    T.DateTime DESC