我有这个USERS
表,用户可以有两种不同的类型(A和B)。我需要每周显示一个包含每种类型聚合的报告。到目前为止我的查询工作得很好,除了几周没有正确分组。在下面的示例中,从1月28日开始的一周应该有一行,而不是两行。
Week Starts |Week| Type A | Type B
------------+----+--------+------
2013-02-04 | 14 | 2 | 26
2013-01-28 | 13 | 5 | 191
2013-01-28 | 13 | 0 | 24
2013-01-21 | 12 | 1 | 134
2013-01-21 | 12 | 0 | 20
2013-01-14 | 11 | 1 | 143
2013-01-14 | 11 | 0 | 2
2013-01-07 | 10 | 0 | 233
2013-01-07 | 10 | 0 | 23
2012-12-31 | 9 | 0 | 12
2012-12-31 | 9 | 4 | 164
2012-12-31 | 9 | 0 | 20
SQL
;with cte as
(
select DATEADD(m,-3,GETDATE()) firstday, DATEADD(m,-3,GETDATE()) + 6 - DATEDIFF(day, 0, DATEADD(m,-3,GETDATE())) %7 lastday, 1 week
union all
select lastday + 1, case when GETDATE() < lastday + 7 then GETDATE() else lastday + 7 end, week + 1
from cte
where lastday < GETDATE()
)
SELECT
cast(firstday as date) 'Week Starts',
cte.week as 'Week',
Sum(CASE WHEN USR_TYPE = 'A' THEN 1 ELSE 0 END) As 'Type A',
Sum(CASE WHEN USR_TYPE = 'B' THEN 1 ELSE 0 END) As 'Type B'
FROM cte left join USERS
ON cte.firstday <= USERS.CREATED
AND cte.lastday > USERS.CREATED
GROUP BY cte.week, cte.firstday, cte.lastday, DATEPART(YEAR,USERS.CREATED), DATEPART(wk,USERS.CREATED)
ORDER BY week desc
我做错了什么?
答案 0 :(得分:5)
如果没有看到users
表中的任何数据,我会猜测一下。
您在CTE中生成的日期列表包括time
。
您可能需要将cast()
和firstday
值lastday
设为date
,或者无需时间生成列表。
来自您的CTE的样本和新的日期投射:
| CASTFIRSTDAY | CASTLASTDAY | WEEK | FIRSTDAY | LASTDAY |
---------------------------------------------------------------------------------------------------------
| 2012-11-05 | 2012-11-11 | 1 | November, 05 2012 20:08:10+0000 | November, 11 2012 20:08:10+0000 |
| 2012-11-12 | 2012-11-18 | 2 | November, 12 2012 20:08:10+0000 | November, 18 2012 20:08:10+0000 |
| 2012-11-19 | 2012-11-25 | 3 | November, 19 2012 20:08:10+0000 | November, 25 2012 20:08:10+0000 |
| 2012-11-26 | 2012-12-02 | 4 | November, 26 2012 20:08:10+0000 | December, 02 2012 20:08:10+0000 |
| 2012-12-03 | 2012-12-09 | 5 | December, 03 2012 20:08:10+0000 | December, 09 2012 20:08:10+0000 |
| 2012-12-10 | 2012-12-16 | 6 | December, 10 2012 20:08:10+0000 | December, 16 2012 20:08:10+0000 |
您可能希望编辑CTE以仅返回date
值:
;with cte as
(
select
cast(DATEADD(m,-3,GETDATE()) as date) firstday,
cast(DATEADD(m,-3,GETDATE()) + 6 - DATEDIFF(day, 0, DATEADD(m,-3,GETDATE())) %7 as DATE) lastday,
1 week
union all
select
cast(DATEADD(DAY, 1, lastday) as date),
case
when cast(GETDATE() as date) < cast(DATEADD(DAY, 7, lastday) as date)
then cast(GETDATE() as date)
else cast(DATEADD(DAY, 7, lastday) as date)
end,
week + 1
from cte
where cast(lastday as date) < cast(GETDATE() as date)
)
select *
from cte