2009-07-23 48 views
9

this question類似,我需要將大量記錄分組爲1小時「存儲桶」。例如,假設我有一個典型的ORDER表,每個訂單附有日期時間。我希望看到每小時的訂單總數。所以我使用SQL大致是這樣的:將SQL結果分組/彙總到1小時存儲桶中

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

的問題是,如果沒有訂單在給定的1小時的「桶」,沒有行被排放到結果集。我希望結果集每24小時都有一排,但如果在特定小時內沒有訂單,只需將訂單數量記錄爲O.

有沒有辦法在單個查詢?請參閱Getting Hourly Statistics Using SQL

+0

這將有助於瞭解您正在使用哪個版本的Pg。 – 2009-07-23 21:54:08

回答

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 
+0

我相信你也可以用類似``替代`ONEHOURSLOTS``(選擇0作爲SLOT_HOUR聯合選擇1作爲SLOT_HOUR聯合..)` - 只有當你死了才能保持在單個查詢中 - yuck:P – Blorgbeard 2009-07-23 21:20:36

+0

你可以做到這一點更容易用戶generate_series()(假設你在postgres上,標籤說你是,但示例查詢不會在那裏工作..) – 2009-07-24 06:55:52

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; 
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]