2011-09-26 144 views
2

我已經研究出如何在SQL Server 2005中使用PIVOT從表中旋轉一行,但是,我不喜歡該方法,因爲我必須對列(貨幣代碼)進行硬編碼,而且我會喜歡讓Pivot動態選擇列。動態SQL Server 2005透視

舉個例子,假設你有如下表(稱爲OrderCash):

OrderID CAD  CHF  EUR  GBP  JPY  NOK  USD 
40  0  0  128.6 552.25 -9232 0  -4762 
41  0  0  250.2 552.25 -9232 0  -4762 
42  233.23 0  552.25 -9232 0  0  -4762 

硬編碼樞紐的說法是:

SELECT OrderID, 
     CurrCode + 'GBP CURNCY' AS Ticker, 
     Cash AS Position 
FROM 
(
    SELECT OrderID, 
     CAD, 
     CHF, 
     EUR, 
     GBP, 
     JPY, 
     NOK, 
     USD 
    FROM OrderCash 
) p 
UNPIVOT 
(
    Cash FOR CurrCode IN 
    (CAD, CHF, EUR, GBP, JPY, NOK, USD) 
) AS unpvt 
WHERE Cash != 0 
And OrderID = 42 

這將返回以下所需表格:

OrderID Ticker   Position 
42  CADGBP CURNCY 233.23 
42  EURGBP CURNCY 552.25 
42  GBPGBP CURNCY -9232 
42  USDGBP CURNCY -4762 

當有人告訴我我需要將澳元作爲表中的新貨幣時,問題會進一步出現在路上嗎?

僅供參考,我有一個返回的所有列名作爲表的表值函數:

ALTER FUNCTION [dbo].[GetTableColumnNames] 
     (
     @TableName NVARCHAR(250), 
     @StartFromColumnNum INT 
     ) 

    RETURNS @ReturnTable TABLE 
     (
     ColName NVARCHAR(250) 
     ) 
AS 

BEGIN 
    INSERT INTO @ReturnTable 
     SELECT COLUMN_NAME from information_schema.columns 
     WHERE TABLE_NAME = @TableName 
      AND ORDINAL_POSITION >= @StartFromColumnNum 
     ORDER BY ORDINAL_POSITION 

    RETURN 
END 

所以容易位已經完成(SELECT * FROM dbo.GetTableColumnNames(「OrderCash」,2 )),我遇到的問題是將這個'動態'表的列名插入到Pivot中?

任何幫助將不勝感激。 非常感謝 Bertie。

+1

我會折騰出(典型和刺激性)實用主義者響應:匯率打交道時和外匯,你可能會更多,更好的數據正常化。似乎更有可能的是,有人總是希望將「多一種貨幣」添加到您的列表中。 –

回答

3

我已經完成了很多這些動態查詢後期...(我的列按月移動客戶端)。下面是做這件事 - 沒有測試,無需調試,可能會有一些錯誤,以消除:

DECLARE 
    @Command  nvarchar(max) 
,@ColumnList nvarchar(max) 
,@OrderId  int 
,@Debug  bit 


-- Build a comman-delimited list of the columns 
SELECT @ColumnList = isnull(@ColumnLIst + ',', , '') + ColName 
from dbo.GetTableColumnNames('OrderCash', 2) 


-- Insert the list of columns in two places in your query 
SET @Command = replace(' 
SELECT OrderID, 
     CurrCode + ‘‘GBP CURNCY’‘ AS Ticker, 
     Cash AS Position 
FROM 
( 
    SELECT OrderID, <@ColumnList> 
    FROM OrderCash 
) p 
UNPIVOT 
( 
    Cash FOR CurrCode IN 
    (<@ColumnList>) 
) AS unpvt 
WHERE Cash != 0 
And OrderID = @OrderId 
', '<@ColumnList>', @ColumnList) 


-- Always include something like this! 
IF @Debug = 1 
    PRINT @Command 

-- Using sp_executeSQL over EXECUTE (@Command) allows you execution 
-- plan resuse with parameter passing (this is the part you may need 
-- to debug on a bit, but it will work) 
EXECUTE sp_executeSQL @Command, N'@OrderId int', @OrderId 
+1

+1,非常好的答案,我即將回答類似的問題,但你的參數更多。我只會添加一個鏈接到您的答案:http://www.sommarskog.se/dynamic_sql.html – Lamak

+0

是的,他是認真理解動態SQL的關鍵。 –

+0

感謝您的幫助。 – Bertie