TSQL计算众多字段的总和

时间:2012-06-15 08:59:26

标签: sql-server tsql loops

我有这样的数据:

Date         Count1 Count2 Count3 ... Countxx
01-05-2012   1      0      1          2
01-05-2012   2      1      3          0
01-05-2012   2      3      3          1
02-05-2012   1      3      2          0
02-05-2012   5      2      0          0

我需要计算按日期分组的各个字段(Count1到Countxx)的总和并写下这个SQL:

select sum(count1), sum(count2), sum(count3), .. , sum(countxx) 
from table1 group by date

我的第一个问题:SQL服务器中是否有任何方法可以自动执行此操作(不知道字段数,因为每次字段的名称和数量都会不同,因此手动编写SQL非常麻烦)。 / p>

其次,如何计算当前行减去前一行的值和前7行的平均值?

谢谢!

2 个答案:

答案 0 :(得分:2)

create procedure USP_FindSum @tablename varchar(100)                
as
begin
 create table #temp(id int identity(1,1),name varchar(100))
 declare @sqlcmd nvarchar(max)=''
 SET @sqlcmd= N'Insert into #temp select name from sys.columns col_table where        
 col_table.object_id=object_id('''+@tablename+''')'
 EXEC sp_executesql @sqlcmd
 declare @sqlseg varchar(max)=''
 declare @tempcount int
 declare @i int=1
 select @tempcount=COUNT(id) from #temp
 while(@i<=@tempcount)
 BEGIN
   declare @CName varchar(100)
   SELECT @CName= name from #temp where id=@i
   if(@i!=@tempcount)
    SET @sqlseg=+@sqlseg+'sum('+@CName+')'+',' 
   else
    SET @sqlseg =+@sqlseg+'sum('+@CName+')'
   SET @i=@i+1
 END
 SET @sqlcmd=N'select '+@sqlseg+' from '+@tablename
 EXEC sp_executesql @sqlcmd
 DROP TABLE #temp
END

假设表中的所有列都是可求和的。由于您的要求很奇怪,这种解决方法也可能如此。

只需将表名作为参数传递并执行,

Exec USP_FindSum '<tablename here>'

答案 1 :(得分:0)

无法对列的变量列表求和,您必须全部指定。

查找上一行的一种方法是outer apply,例如:

select  Date
,       cur.count1 - isnull(prev.count1,0) as Delta1
from    Table1 cur
outer apply
        (
        select  top 1 *
        from    Table1 prev
        where   prev.Date < cur.Date
        order by
                prev.Date desc
        ) prev

另一种方法是根据row_number()加入表:

; with  t1 as
        (
        select  row_number() over (order by Date) as rn
        ,       *
        from    Table1
        )
select  Date,
,       cur.count1 - isnull(prev.count1,0) as Delta
from    t1 cur
left join    
        t1 prev
on      cur.rn = prev.rn + 1