Sql server SQL Server:使用CTE对年度数据进行分组

Sql server SQL Server:使用CTE对年度数据进行分组,sql-server,group-by,Sql Server,Group By,示例数据: create table #temp ( dateRef date, a float, b float, c float ) insert into #temp (dateRef, a, b, c) values ('20050101',1000,500,0) insert into #temp (dateRef, a, b, c) values ('20050201',1000,1000,0) insert into #temp (dateRe

示例数据:

create table #temp
(
    dateRef date,
    a float,
    b float,
    c float  
)

insert into #temp (dateRef, a, b, c) values ('20050101',1000,500,0)
insert into #temp (dateRef, a, b, c) values ('20050201',1000,1000,0)
insert into #temp (dateRef, a, b, c) values ('20050301',4000,4000,3000)
insert into #temp (dateRef, a, b, c) values ('20050401',2000,2000,1000)
insert into #temp (dateRef, a, b, c) values ('20050501',1000,2000,0)
insert into #temp (dateRef, a, b, c) values ('20050601',2000,2000,0)
insert into #temp (dateRef, a, b, c) values ('20050701',2000,2000,1000)
insert into #temp (dateRef, a, b, c) values ('20050801',2000,2000,1000)
--- 
insert into #temp (dateRef, a, b, c) values ('20060301',1000,1000,0)
insert into #temp (dateRef, a, b, c) values ('20060601',1000,1000,0)
insert into #temp (dateRef, a, b, c) values ('20060701',2000,2000,0)
insert into #temp (dateRef, a, b, c) values ('20060801',2000,2000,1000)
---
insert into #temp (dateRef, a, b, c) values ('20070101',1000,1000,0)
达到预期效果的最佳方式是什么?(使用SQL Server 2012)

逻辑:
当C>0时,为连续日期和年份间隔求和所有之前的A,例如:当data='20050301',C=3000(C>0),那么我需要求和(A)如果日期是连续的(在本例中,它们是20050101-20050201-20050301),当data=20050701 C=1000(C>0),而不是sum(A)如果日期是连续的(在本例中,它们是20050501-20050601-20050701),当date='20050801'c=1000(c>0)时,我需要求和(a),在这种情况下,只有年份20050801,依此类推,对于
按年份分组
数据,我们可以尝试此方法-

select
    year(dateref) as year,
    sum(a) as a,
    sum(b) as b,
    sum(c) as c
from #temp
group by year(dateref)
输出-

year    a       b       c
2005    15000   15500   6000
2006    6000    6000    1000
2007    1000    1000    0
请尝试以下查询:

select
    dateRef = max(dateRef), a = sum(a), b = sum(b), c = sum(c)
from (
    select 
        *, rn = datediff(mm, '19000101', dateRef) - row_number() over (order by dateRef)
        , grp = isnull(sum(iif(c > 0, 1, 0)) over (order by dateRef rows between unbounded preceding and 1 preceding), 0)
    from 
        #temp
) t
group by rn, grp
having sum(c) > 0
查询中有两列用于分组
rn
-查找连续行,
grp
-将c>0的行与c=0的前一行分组

输出

dateRef     a       b       c
---------------------------------
2005-03-01  6000    5500    3000
2005-04-01  2000    2000    1000
2005-07-01  5000    6000    1000
2005-08-01  2000    2000    1000
2006-08-01  5000    5000    1000

你吃过什么东西吗?堆栈溢出不是一种代码编写服务(通常)。您可以按
YEAR(dateRef)
进行分组,但对于大量数据来说,这并不适用。这就是为什么大多数数据库都有一个
日期
日历
表,其中包含日期、年、月、日、名称等值,例如10年。顺便说一句,您的结果显示按年和月分组,而不是按年分组。我正在尝试使用CTE,但不能同时使用Group by。只有当c>0和DataRef连续时,我才需要求和(a),当年假到新年仅分组是不够的时,我担心OP的样本输出看起来不同。但他没有解释它的逻辑。逻辑是,当C>0时,对所有之前的A进行求和,例如:“20050101',1000500,0'20050201',10001000,0'20050301',400040003000,这里C=3000,如果日期是连续的,那么我需要求和(A)(在本例中,它们是1-2-3)。分组方法在这里是不够的,我正在尝试用CTEthanks来解决这个问题,我已经尝试过了,但是只返回了4条记录,最后的20060801条不会返回,我不知道为什么,我正在尝试理解
dateRef     a       b       c
---------------------------------
2005-03-01  6000    5500    3000
2005-04-01  2000    2000    1000
2005-07-01  5000    6000    1000
2005-08-01  2000    2000    1000
2006-08-01  5000    5000    1000