按日期范围分组,选择最大计数

时间:2018-04-20 04:06:01

标签: sql sql-server-2012

我在开发实现以下目标的查询时遇到问题。我试图确定每个班次的用户(班次是12小时并从7:30AM to 7:30PM开始运行,然后再次7:30PM to 7:30AM期间拥有该班次期间的最多记录数。

我的数据看起来像这样:

DateTime            |   UserName
2017-01-01 07:45:00 |   User1
2017-01-01 08:46:00 |   User2
2017-01-01 09:45:00 |   User1
2017-01-01 20:46:00 |   User2
2017-01-01 22:58:00 |   User1
2017-01-01 23:30:00 |   User2

理想情况下,我正在寻找的输出是:

DateTime            |   UserName
2017-01-01 07:30:00 |   User1
2017-01-01 19:30:00 |   User2

由于User1在从2017-01-01 07:30:00 (2017-01-01 07:30:00 - 2017-01-01 19:30:00)开始的班次期间获得的记录最多,而且在从2017-01-01 07:30:00 (2017-01-01 19:30:00 - 2017-01-02 7:30:00)开始的班次期间,User2的记录最多

我希望有意义,如果有人能提供帮助,我将不胜感激。

2 个答案:

答案 0 :(得分:0)

此解决方案在CTE中计算每个用户的时间戳计数,出现在早班或晚班。然后,我查询CTE并显示早班或晚班,具体取决于哪一个有较大的计数。

WITH cte AS (
    SELECT
        CONVERT(VARCHAR(10), DateTime, 111) AS DateTime,
        UserName,
        COUNT(CASE WHEN 60*DATEPART(HOUR, DateTime) +
                  DATEPART(MINUTE, DateTime) >= 450 AND
                  60*DATEPART(HOUR, DateTime) +
                  DATEPART(MINUTE, DateTime) < 1170 THEN 1 END) AS m_cnt,
        COUNT(CASE WHEN 60*DATEPART(HOUR, DateTime) +
                  DATEPART(MINUTE, DateTime) < 450 OR
                  60*DATEPART(HOUR, DateTime) +
                  DATEPART(MINUTE, DateTime) >= 1170 THEN 1 END) AS e_cnt
    FROM yourTable
    GROUP BY CONVERT(VARCHAR(10), DateTime, 111), UserName
)

SELECT
    UserName,
    CASE WHEN m_cnt > e_cnt
         THEN DateTime + ' 07:30:00' ELSE DateTime + ' 19:30:00' END AS DateTime
FROM cte
ORDER BY
    DateTime, UserName;

    UserName    DateTime
1   User1       2017-01-01 07:30:00
2   User2       2017-01-01 19:30:00

Demo

答案 1 :(得分:0)

你可以试试这个。

DECLARE @MyTable TABLE ([DateTime] DATETIME, UserName VARCHAR(10))
INSERT INTO @MyTable VALUES
('2017-01-01 07:45:00', 'User1'),
('2017-01-01 08:46:00', 'User2'),
('2017-01-01 09:45:00', 'User1'),
('2017-01-01 20:46:00', 'User2'),
('2017-01-01 22:58:00', 'User1'),
('2017-01-01 23:30:00', 'User2')


SELECT UserName, [DateTime] FROM (
    SELECT 
        UserName
        , SHF.SDate [DateTime]
        , ROW_NUMBER() OVER( PARTITION BY SHF.SDate ORDER BY COUNT(*) DESC) RN 
    FROM @MyTable T
        CROSS APPLY( VALUES( CONVERT(VARCHAR(10), T.[DateTime], 112) + ' 07:30', CONVERT(VARCHAR(10), T.[DateTime], 112) + ' 19:29' ),
                           ( CONVERT(VARCHAR(10), T.[DateTime], 112) + ' 19:30', DATEADD(DAY,1,CONVERT(VARCHAR(10), T.[DateTime], 112) + ' 07:29'))
        ) SHF ( SDate ,EDate ) 
    WHERE T.[DateTime] BETWEEN SHF.SDate AND SHF.EDate
    GROUP BY 
        UserName
        , SHF.SDate
) AS A
WHERE RN = 1

结果:

UserName   DateTime
---------- -----------------------
User1      2017-01-01 07:30
User2      2017-01-01 19:30