GROUP BY几个小时

时间:2014-09-23 08:38:58

标签: sql tsql sql-server-2008-r2

我有一张表,我们的产品记录了它的活动日志。该产品每天23:00开始工作,通常工作一到两个小时。这意味着一旦批次在23:00开始,它将在第二天凌晨1点结束。

现在,我需要统计每批注册的帖子数量,但无法找出允许我实现此目的的脚本。到目前为止,我有以下SQL代码:

SELECT COUNT(*), DATEPART(DAY,registrationtime),DATEPART(HOUR,registrationtime)
FROM RegistrationMessageLogEntry
WHERE registrationtime > '2014-09-01 20:00'
GROUP BY DATEPART(DAY, registrationtime), DATEPART(HOUR,registrationtime)
ORDER BY DATEPART(DAY, registrationtime), DATEPART(HOUR,registrationtime)

导致以下

count   day hour
....
1189    9   23
8611    10  0
2754    10  23
6462    11  0
1885    11  23

即。我希望9号23:00的号码与10号00:00,10号23:00和11号00:00的号码分组,依此类推。我怎么能这样做?

5 个答案:

答案 0 :(得分:2)

你可以很容易地做到。使用DATEADD为原始registrationtime添加一小时。如果您这样做,所有registrationtimes都将移至同一天,您可以按日分组。

您也可以使用CASE WHEN以更复杂的方式进行此操作,但这对于这个简单解决方案的看法来说太过分了。

答案 1 :(得分:0)

几天前我不得不做类似的事情。我有固定的时间跨度,工作班次分组,其中一个可以在一天晚上10点开始,第二天早上6点结束。

我做的是:

  1. 定义一个"班次日期",这是表格中每个条目的班次开始时零时间戳的日子。我能够通过检查条目的时间戳是否在凌晨0点到早上6点之间来完成。在这种情况下,我只采用了此DATEADD(dd, -1, entryDate)的日期,该日期在上午0点到早上6点之间返回所有条目。
  2. 我还为班次添加了一个ID。第一个为0(早上6点到下午2点),第二个为1个(下午2点到晚上10点),最后一个为3个(晚上10点到早上6点)。
  3. 然后,我可以对班次日期和班次ID进行分组。
  4. 示例:

    考虑以下来源条目:

    Timestamp            SomeData
    =============================
    2014-09-01 06:01:00  5
    2014-09-01 14:01:00  6
    2014-09-02 02:00:00  7
    

    第一步扩展了表格如下:

    Timestamp            SomeData    ShiftDay
    ====================================================
    2014-09-01 06:01:00  5           2014-09-01 00:00:00
    2014-09-01 14:01:00  6           2014-09-01 00:00:00
    2014-09-02 02:00:00  7           2014-09-01 00:00:00
    

    第二步扩展了表格如下:

    Timestamp            SomeData    ShiftDay              ShiftID
    ==============================================================
    2014-09-01 06:01:00  5           2014-09-01 00:00:00   0
    2014-09-01 14:01:00  6           2014-09-01 00:00:00   1
    2014-09-02 02:00:00  7           2014-09-01 00:00:00   2
    

答案 2 :(得分:0)

您可以编写CASE声明,如下所示

CASE WHEN DATEPART(HOUR,registrationtime) = 23
     THEN DATEPART(DAY,registrationtime)+1
END,
CASE WHEN DATEPART(HOUR,registrationtime) = 23
    THEN 0
END

答案 3 :(得分:0)

以下查询将为您提供您期望的内容..

;WITH CTE AS
(
SELECT COUNT(*) Count, DATEPART(DAY,registrationtime) Day,DATEPART(HOUR,registrationtime) Hour,
RANK() over (partition by DATEPART(HOUR,registrationtime) order by DATEPART(DAY,registrationtime),DATEPART(HOUR,registrationtime)) Batch_ID
FROM RegistrationMessageLogEntry
WHERE registrationtime > '2014-09-01 20:00'
GROUP BY DATEPART(DAY, registrationtime), DATEPART(HOUR,registrationtime)
)
SELECT SUM(COUNT) Count,Batch_ID
FROM CTE
GROUP BY Batch_ID
ORDER BY Batch_ID

答案 4 :(得分:0)

如果您向registrationtime添加一小时,则可以按日期部分进行分组:

GROUP BY
  CAST(DATEADD(HOUR, 1, registrationtime) AS date)

如果必须在输出中准确反映开始时间(9, 2310, 23而不是10, 011, 0),您可以将其作为{{ SELECT子句中的1}}:

MIN(registrationtime)

最后,如果您不知道,可以通过ORDER BY中的别名引用列:

SELECT
  count = COUNT(*),
  day   = DATEPART(DAY, MIN(registrationtime)),
  hour  = DATEPART(HOUR, MIN(registrationtime))

只是为了让你不必重复表达。