Sql 动态返回行中所有列的总和

Sql 动态返回行中所有列的总和,sql,sql-server,tsql,for-loop,Sql,Sql Server,Tsql,For Loop,是否有一种方法可以使用T-SQL动态地对一行中返回的每一列的值求和?我正在使用SQLServer2008。我可以想象有某种表值函数魔法可以实现这一点,但我一直没有幸运地找到答案 数据如下所示: id type value date 1 PROD1 5 2014-08 2 PROD2 3 2014-08 3 PROD3 4

是否有一种方法可以使用T-SQL动态地对一行中返回的每一列的值求和?我正在使用SQLServer2008。我可以想象有某种表值函数魔法可以实现这一点,但我一直没有幸运地找到答案

数据如下所示:

id        type        value      date
1         PROD1       5          2014-08
2         PROD2       3          2014-08
3         PROD3       4          2014-08
4         PROD4       3          2014-08
5         PROD2       3          2014-07
6         PROD3       5          2014-06
以及一个TVF,它接受日期作为参数并返回:

PROD1 PROD2   PROD3   PROD4
5     3       4       3
现在,我当然可以在原始表上运行以下操作:

SELECT * FROM tbl WHERE date = '2014-08'
回来

id        type        value      date
1         PROD1       5          2014-08
2         PROD2       3          2014-08
3         PROD3       4          2014-08
4         PROD4       3          2014-08
但是。。。我需要计算这些值。我可能需要将PROD1和PROD3的总和结合起来,或者可能得到总和(PROD1,PROD3)占总总和的百分比

我不想这么做

SELECT *,
  SUM(
    SELECT SUM(value) 
    FROM tbl 
    WHERE [date] = '2014-08'
    AND ( [type] = 'PROD1' OR [type] = 'PROD3')
  ) AS [SUM_P1+P3],

 SUM(
    SELECT SUM(value) 
    FROM tbl 
    WHERE [date] = '2014-08'
  ) AS [TOTAL_PROD],

 -- Percentage of (PROD1+PROD3)
 (
   SUM(
      SELECT SUM(value) 
      FROM tbl 
      WHERE [date] = '2014-08'
      AND ( [type] = 'PROD1' OR [type] = 'PROD3')
   ) AS [SUM_P1+P3],
   /
   SUM(
      SELECT SUM(value) 
      FROM tbl 
      WHERE [date] = '2014-08'
   )
 ) AS [PCT_P1+P3]

 ...
垂直视图省去了我不断重新查询数据库的麻烦。手动将每列添加到SQL查询中不是一个选项,因为表的宽度可能会有所不同。我不得不手动写出(V1+V2+V3+V4…),这也让我觉得很笨拙。我该如何迭代T-SQL中的每一列?有类似这样的for循环吗

DECLARE @mysum int;
for(col in row) {
  SET @mysum = @mysum+col;
}

**如果有一种方法可以检测列数据类型是否为整数,那就有好处了。

我认为您应该回复lc的注释,因为它非常相关,但您可以使用动态SQL实现这一点

USE mydatabase
DECLARE 
    @table varchar(max) = 'myTable',
    @exec nvarchar(max);

select
    @exec = 'select SUM('+RIGHT(c,LEN(c)-1)+') from '+@table
from (
    select
        '+'+c.name 
    from sys.columns c
    inner join sys.tables t on
        c.object_id = t.object_id
    inner join sys.types ty on
        c.user_type_id = ty.user_type_id
    where
        ty.name in ('int') and
        t.name = PARSENAME(@table,1)
    FOR XML PATH('')
) T (c)
print @exec
exec sp_executesql @exec

您需要参考信息\u SCHEMA.COLUMNS视图并动态构建SQL查询。创建一个视图,每次需要所有列的总和时都使用它。我觉得这个问题有点像XY问题。你能解释一下你正在努力实现的目标吗?也就是说,1)为什么要在一行中任意添加列;2) 为什么不明确地知道表的模式;3)为什么要在数据库引擎而不是表示层中执行此操作?我会尽全力。1) 也许我做错了。我已经添加了一些关于数据是如何进入的详细信息。2) 在这个时候,我可以控制一切,但当我把它交出来的时候,有一个很好的机会,更多的PROD列将被添加,我正试图让它尽可能动态。3) 将这些值烘焙回数据库是一种可能的情况,这肯定会起作用。如果有人能找到比我描述的更简单的解决方案,我仍然愿意接受建议。@RyanDunphy如果你想要更多建议,我建议你在一两天内不回答这个问题。人们更倾向于关注未回答的问题。