1

I have multiple columns with some amount in a table and I want to show the total of all those amounts in the last Total column. I have a table in sql which looks somewhat like this,

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

I do not want to do sum(col1 + col2 + ..) like this because there are many columns. Is there another way to get the sum using a where clause like **where columnname.name like '%Amt%'**?

I am trying to use UNPIVOT and I came up with the following code but it is not working,

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%')))

Any ideas will be helpful.

StuartLC
  • 104,537
  • 17
  • 209
  • 285
Arpita
  • 445
  • 3
  • 14
  • 28

3 Answers3

3

The dyanamic UNPIVOT solution would need to use one of the GROUP_CONCAT hacks to scrape the column names you've obtained via sys.syscolumns into a comma delimited string before entering into the UNPIVOT.

But if blinding performance isn't a requirement, how about invoking xquery to do this in Xml? It's much simpler:

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

Basically, after rolling up the whole table into Xml, it then iterates the rows (//row), evaluating the sum of all the elements with a name which contains _Amt.

The real benefit is that you don't need to bother figuring out the actual column names at all - that'll be deferred into the xpath.

Community
  • 1
  • 1
StuartLC
  • 104,537
  • 17
  • 209
  • 285
1

This is an unusual table layout, and I don't think there's a perfect shortcut for what you want to do. One option is to push the addition to the table level with a computed column:

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

After the initial trouble of setting up the computed column, your future queries get a lot easier:

SELECT Total FROM myTable
Ed Gibbs
  • 25,924
  • 4
  • 46
  • 69
1

I'll be using Dynamic SQL. Google a simple example for this.

1 - Generate a string with all column names - c1+c2+c3...

2 - Create a string with full sql query, using 1 also.

3 - Execute string in 2 as dynamic sql.

I'll combine 1 and 2 though.

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)
Erran Morad
  • 4,563
  • 10
  • 43
  • 72