Sql CTE表现不符合预期的每周合计

Sql CTE表现不符合预期的每周合计,sql,sql-server-2008,tsql,grouping,Sql,Sql Server 2008,Tsql,Grouping,我有这个用户表,其中的用户可以是两种不同类型的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-2

我有这个用户表,其中的用户可以是两种不同类型的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


我做错了什么?

在没有看到用户表中的任何数据的情况下,我将进行猜测

您在CTE中生成的日期列表包括时间

您可能需要将firstday和lastday值强制转换为日期,或者在没有时间的情况下生成列表

来自您的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以返回仅限日期的值:

;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

是的!我更换了cte上的。第一天@greener我很高兴它能工作。我一运行您的CTE,就有一种感觉,这就是问题所在@我提供了一个新的CTE,它只返回日期值。使用递归CTE生成序列并不比使用游标好多少,最好避免使用。生成序列的一种更简单的方法是使用系统表master.dbo.spt_值,如何生成列表的一个示例是,对于像您这样只有14周的较小循环,它应该不重要,但是对于较大的序列,您应该注意到一个差异。
;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