2011-01-26 45 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;