2014-08-28 36 views
0

是否有一種方法可以動態地使用T-SQL來總結一行中返​​回的每列的值?我正在使用SQL Server 2008.我會想象有某種表值函數可以實現這個功能,但我在搜索答案時並不幸運。動態地返回一行中所有列的SUM

的數據來自於這樣的:

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的總和相加,或者可以獲得總和(SUM)的SUM(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; 
} 

**獎勵積分,如果我有辦法來檢測,如果該列的數據類型是整數。

+0

您需要引用INFORMATION_SCHEMA.COLUMNS視圖並動態構建SQL查詢。 – wdosanjos 2014-08-28 17:55:53

+0

創建一個視圖一次,並在每次需要所有列的總和時使用它 – 2014-08-28 17:59:47

+4

這個問題讓我感到一點XY問題。你能解釋一下你想要完成的事情嗎?也就是說,1)你爲什麼要在一行中任意添加一列; 2)爲什麼你不明確知道表的模式; 3)爲什麼你會在數據庫引擎中這樣做,而不是表示層? – 2014-08-28 18:00:30

回答

2

我認爲你應該回復lc的評論,因爲它非常相關,但你可以通過動態SQL來實現。

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

select 
    @exec = 'select SUM('+RIGHT(c,LEN(c)-1)+') from '[email protected] 
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 
+0

這絕對有效。如果有人能找到比我所描述的更簡單的解決方案,我仍然樂於接受建議。 – 2014-08-28 18:48:01

+0

@RyanDunphy如果你想要更多的建議,我建議留下這個一兩天沒有答案。人們更可能看到未解決的問題。 – 2014-08-28 18:52:13