对SQL的结果进行分组选择

时间:2018-03-08 05:22:14

标签: sql sql-server tsql sql-server-2012

我试图实现我认为的简单的mssql select语句结果分组,如下所示;

SELECT
    DATEPART( day, Review.[LocalTimeGenerated] ) AS DayNum,
    Review.[LocalTimeGenerated] AS LocalDate,
    ( Users.[FirstName] + ' ' + Users.[SecondName] ) AS FullName,
    SUBSTRING(
        Review.[Text],
        PATINDEX(
            '%into %',
            Review.[Text]
        ) + 5,
    50
) AS LastDoorEntered                                        /* return only the door name */

FROM [LOGS].[dbo].[Review] Review

INNER JOIN [DATA].[dbo].[TUser] Users
ON Review.[Entity_2_ID] = Users.[ID]

WHERE Review.[LocalTimeGenerated] > GETDATE() - 9           /* get the last 9 days */ 
AND Review.[Entity_3_ID] = '4503603922337793'               /* id of the door? */
AND ( Users.[FirstName] + ' ' + Users.[SecondName] ) = '[username]'

ORDER BY [Fullname] ASC, [LocalDate] DESC

具有以下结果;

DayNum  LocalDate                       FullName     LastDoorEntered
8       2018-03-08 07:20:08.7370000     [username]   Main Office Entrance
7       2018-03-07 08:15:31.5970000     [username]   Main Office Entrance
6       2018-03-06 14:41:43.3230000     [username]   Main Office Entrance
6       2018-03-06 08:52:15.9870000     [username]   Main Office Entrance
5       2018-03-05 08:52:45.4170000     [username]   Main Office Entrance
1       2018-03-01 14:43:12.7670000     [username]   Main Office Entrance
1       2018-03-01 13:10:29.6400000     [username]   Main Office Entrance
1       2018-03-01 12:18:57.1670000     [username]   Main Office Entrance
1       2018-03-01 11:32:17.5970000     [username]   Main Office Entrance
1       2018-03-01 10:43:04.2170000     [username]   Main Office Entrance
1       2018-03-01 08:05:00.1530000     [username]   Main Office Entrance
28      2018-02-28 15:19:22.4270000     [username]   Main Office Entrance
28      2018-02-28 13:17:04.9100000     [username]   Main Office Entrance
28      2018-02-28 12:06:50.3970000     [username]   Main Office Entrance
28      2018-02-28 08:52:09.6600000     [username]   Main Office Entrance

我遇到的麻烦是我需要根据当天返回分组结果(基本上我只需要查看每天的第一个条目)。以下是结果需要;

DayNum  LocalDate                       FullName     LastDoorEntered
8       2018-03-08 07:20:08.7370000     [username]   Main Office Entrance
7       2018-03-07 08:15:31.5970000     [username]   Main Office Entrance
6       2018-03-06 08:52:15.9870000     [username]   Main Office Entrance
5       2018-03-05 08:52:45.4170000     [username]   Main Office Entrance
1       2018-03-01 08:05:00.1530000     [username]   Main Office Entrance
28      2018-02-28 08:52:09.6600000     [username]   Main Office Entrance

我希望我可以简单地使用GROUP BY DayNum,但显然你不能用别名分组。

  

无效的列名称' DayNum'。

将逻辑向下移动到GROUP BY子句也没有工作(...不包含在聚合函数或GROUP BY子句中。)

我尝试了两个单独的SELECT并通过ID列(在上面的示例中未使用)将它们合并在一起,但没有成功。使用Select multiple columns from table but Group By one上显示的最大技巧也没有运气。

有没有办法可以让它发挥作用,还是我在前端的事实后坚持这样做?

2 个答案:

答案 0 :(得分:2)

您不能通过别名进行分组,但在大多数SQL实现中,可以按函数的输出进行分组。只需group by DATEPART( day, Review.[LocalTimeGenerated] ),就可以了。

您当然需要将所有其他选择包装在聚合函数中(例如min(Review.[LocalTimeGenerated]) AS LocalDate

答案 1 :(得分:2)

您可以使用ROW_NUMBER

SELECT * FROM (
    SELECT
        DATEPART( day, Review.[LocalTimeGenerated] ) AS DayNum,
        Review.[LocalTimeGenerated] AS LocalDate,
        ( Users.[FirstName] + ' ' + Users.[SecondName] ) AS FullName,
        SUBSTRING(
            Review.[Text],
            PATINDEX(
                '%into %',
                Review.[Text]
            ) + 5,
        50
    ) AS LastDoorEntered                                        /* return only the door name */
    , ROW_NUMBER() OVER(PARTITION BY CAST(Review.[LocalTimeGenerated] AS DATE) ORDER BY Review.[LocalTimeGenerated]) RN 

    FROM [LOGS].[dbo].[Review] Review

    INNER JOIN [DATA].[dbo].[TUser] Users
    ON Review.[Entity_2_ID] = Users.[ID]

    WHERE Review.[LocalTimeGenerated] > GETDATE() - 9           /* get the last 9 days */ 
    AND Review.[Entity_3_ID] = '4503603922337793'               /* id of the door? */
    AND ( Users.[FirstName] + ' ' + Users.[SecondName] ) = '[username]'
) T
WHERE RN = 1
ORDER BY [Fullname] ASC, [LocalDate] DESC