将SQL结果分组/聚合为1小时存储桶

时间:2009-07-23 21:13:16

标签: sql sql-server postgresql

this question类似,我需要将大量记录分组为1小时“桶”。例如,假设我有一个典型的ORDER表,每个订单附有一个日期时间。我希望看到每小时的订单总数。所以我大致使用SQL:

SELECT datepart(hh, order_date), SUM(order_id)
FROM ORDERS
GROUP BY datepart(hh, order_date)

问题是如果在给定的1小时“桶”中没有订单,则不会向结果集中发出任何行。我希望结果集在24小时内每行都有一行,但如果在特定小时内没有订单,只需将订单数记录为O.

有没有办法在单个查询中执行此操作?

另见Getting Hourly Statistics Using SQL

3 个答案:

答案 0 :(得分:8)

以前的一些答案建议使用小时表并使用UNION查询填充它;使用公用表表达式可以做得更好:

; WITH [Hours] ([Hour]) AS
(
SELECT TOP 24 ROW_NUMBER() OVER (ORDER BY [object_id]) AS [Hour]
FROM sys.objects
ORDER BY [object_id]
)
SELECT h.[Hour], o.[Sum]
FROM [Hours] h
LEFT OUTER JOIN (
   SELECT datepart(hh, order_date) as [Hour], SUM(order_id) as [Sum]
      FROM Orders
      GROUP BY datepart(hh, order_date) 
) o
ON h.[Hour] = o.[Hour]

答案 1 :(得分:7)

您需要预先填充的表格(或返回表格结果集的函数)才能加入,其中包含您在结果中所需的所有1小时广告位。

然后你用它做一个OUTER JOIN,你应该全部搞定。

这样的事情:

SELECT SLOT_HOUR, SUM(order_id)
FROM
    ONEHOURSLOTS
    LEFT JOIN ORDERS ON DATEPART(hh, order_date) = SLOT_HOUR
GROUP BY SLOT_HOUR

答案 2 :(得分:2)

创建一个小时表,可以“保持”或“即时”合成:

SELECT h.hour, s.sum
FROM (
   SELECT 1 as hour
   UNION ALL SELECT 2
   UNION ALL SELECT 3
   ...
   UNION ALL SELECT 24) as h
LEFT OUTER JOIN  (
   SELECT datepart(hh, order_date) as hour, SUM(order_id) as sum
      FROM ORDERS
      GROUP BY datepart(hh, order_date) ) as s 
  ON h.hour = s.hour;