2011-01-26 42 views
11

我有下面的代碼,它將顯示爲例如「Y:2010 - Week:50」的幾周內的一些事件(YYYY-MM-DD HH:MM:SS)進行分組。按周分組,如何獲得空周?

SELECT DATE_FORMAT(date, 'Y:%X - Week:%V') AS regweek, COUNT(*) as number 

它工作的很好,但我想要返回所有星期,即使沒有放置任何事件。

如果沒有事件被註冊在第三個星期,此刻我得到:

week 1: 10 
week 2: 1 
week 4: 2 

我想獲得:

week 1: 10 
week 2: 1 
week 3: 0 
week 4: 2 
+0

你想*所有*星期以來?剛開始的時候? – thkala 2011-01-26 14:25:19

+1

從第一件事發生的那一週起,或者過去的N個月也可以。它應該只是一個「連續」的時間段 – Danilo 2011-01-26 14:29:56

回答

8

SQL不能返回不存在的行一些桌子。爲了達到你想要的效果,你需要一個星期(WeekNo INT),每年可能每週有一行(根據你的計數方式,IIRC可能是53或54周)。

然後,加入該表到你與外部規則的結果JOIN得到中添加的額外幾周

SELECT DATE_FORMAT(date, 'Y:%X - Week:%V') AS regweek, COUNT(date) as number 
    FROM YourTable RIGHT OUTER JOIN Weeks ON WEEK(YourTable.date) = Weeks.WeekNo 

[更新]:張數(日)的用戶,而不是COUNT(*) 。加入COUNT時,SQL不會在日期列中包含NULL值。由於錯過的星期內沒有任何日期,因此這些星期將正確地給你0個事件。

+0

感謝您的提示。我試圖按照這種方式,但即使在那一週沒有事件,正確的加入也會在特定的一週返回數字= 1,對吧? – Danilo 2011-01-26 16:00:39

0

這是數字/計數表的問題 - 只是一個簡單的表,從0到任意數。他們一般都很有用,我總是建議將它們添加到數據庫中。

有了這個,你可以相對容易地生成一個星期列表,而不需要特定的預先計算的星期表(因此你不需要一個巨大的表或者擔心用完幾周),然後左連接那就是違反你的約會名單,以顯示所有星期的約會。

對於快速啓動:

declare @min datetime 
set  @min ='2010-01-01' 

select 
    dateadd(wk, number, @min) as weekDate 
from 
    numbers 
where 
    number between 0 and datediff(wk,@min,getdate()) 

1

最後我決定來解決這個問題如下,開創了幾個星期的臨時表和使用是在發現代碼在上面回答。

CREATE TEMPORARY TABLE weeks (
     id INT 
     ); 
INSERT INTO weeks (id) VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12), (13), (14), (15), (16), (17), (18), (19), (20), (21), (22), (23), (24), (25), (26), (27), (28), (29), (30), (31), (32), (33), (34), (35), (36), (37), (38), (39), (40), (41), (42), (43), (44), (45), (46), (47), (48), (49), (50), (51), (52), (53), (54); 
SELECT 
w.id, COUNT(c.issuedate) as numberPerWeek 
FROM tableName c RIGHT OUTER JOIN weeks w ON WEEK(c.issuedate) = w.id group by w.id;