Sql server 2005 动态SQLServer2005Pivot

Sql server 2005 动态SQLServer2005Pivot,sql-server-2005,tsql,Sql Server 2005,Tsql,我已经解决了如何在SQLServer2005中使用pivot从表中透视一行,但是,我不喜欢这种方法,因为我必须硬编码列货币代码,我希望pivot动态选择列 例如,假设您有一个名为OrderCash的下表: 硬编码的Pivot语句是: SELECT OrderID, CurrCode + 'GBP CURNCY' AS Ticker, Cash AS Position FROM ( SELECT OrderID, CAD,

我已经解决了如何在SQLServer2005中使用pivot从表中透视一行,但是,我不喜欢这种方法,因为我必须硬编码列货币代码,我希望pivot动态选择列

例如,假设您有一个名为OrderCash的下表:

硬编码的Pivot语句是:

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 
简单的一点是从dbo.GetTableColumnNames'OrderCash'中选择*,2,我遇到的问题是将这个带有列名的“动态”表插入到透视中

任何帮助都将不胜感激。 非常感谢
伯蒂。

最近我做了太多的动态查询。。。我的专栏每月都会随着客户的变化而变化。这里有一种方法不用测试,不用调试,可能会有一些bug需要解决:

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,非常好的答案,我正要回答类似的问题,但您的答案更参数化。我只想给你的答案添加一个链接:是的,他是认真理解动态SQL的关键。
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