如何动态计算sql中多个未知列的总和?

时间:2014-12-19 19:05:12

标签: sql-server

我在表格中有多个列有一些金额,我想在最后一个总计列中显示所有这些金额的总和。我在sql中有一个表,看起来有点像这样,

A_Amt  B_Amt  C_Amt  D_Amt  E_Amt  F_Amt ... Total
------------------------------------------------
 15     20     25     30     35    40       

我不想这样做sum(col1 + col2 + ..),因为有很多列。是否有其他方法可以使用像**where columnname.name like '%Amt%'**这样的where子句来获取总和?

我正在尝试使用UNPIVOT,我想出了以下代码,但它无效,

select Product_ID, Amount
FROM Products
unpivot
(Amount for Product_ID in 
(select c.name + '' from syscolumns c(nolock) where (id = 
(select id from dbo.sysobjects where name = 'Products'))
and (c.name like '%Amt%')))

任何想法都会有所帮助。

3 个答案:

答案 0 :(得分:3)

在进入UNPIVOT之前,dyanamic UNPIVOT解决方案需要使用其中一个GROUP_CONCAT hacks将您通过sys.syscolumns获得的列名称删除为逗号分隔的字符串。

但是如果盲目性能不是一个要求,那么如何调用xquery在Xml中执行此操作呢?它简单得多:

declare @xmlResult xml=
(   
    select  * 
    from    Foo 
    for xml PATH
);

SELECT Nodes.node.value('sum(*[contains(local-name(.), "_Amt")])', 'decimal(15,2)') AS Total
  FROM
  @xmlResult.nodes('//row') as Nodes(node);

With a SqlFiddle here

基本上,在将整个表格汇总到Xml之后,它会迭代行(//row),使用包含name的{​​{1}}来评估所有元素的总和。< / p>

真正的好处是,您根本不需要费心找出实际的列名称 - 这将被推迟到_Amt

答案 1 :(得分:1)

这是一个不寻常的表格布局,我认为没有一个完美的快捷方式,你想做什么。一种选择是使用计算列将添加推送到表级别:

ALTER TABLE mytable ADD Total AS A_Amt + B_Amt + ... + zz_Amt;

在设置计算列的初始问题之后,您将来的查询变得更加容易:

SELECT Total FROM myTable

答案 2 :(得分:1)

我将使用动态SQL。 Google就是一个简单的例子。

1 - 生成包含所有列名称的字符串 - c1 + c2 + c3 ...

2 - 创建一个带有完整SQL查询的字符串,也使用1。

3 - 在2中执行字符串作为动态sql。

我会将1和2结合起来。

declare @sql  varchar(max)
set @sql = 'SELECT ' 

declare @tbl varchar(100)
set @tbl = 'temp' -- put your table name here

SELECT @sql = @sql + COLUMN_NAME + '+'
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @tbl 
-- AND TABLE_SCHEMA='junk'

set @sql = LEFT(@sql, LEN(@sql) - 1)
set @sql = @sql + ' FROM ' + @tbl

select @sql

-- dynamic sql

exec(@sql)