sql-server-2005 - 动态 SQL Server 2005 枢轴

标签 sql-server-2005 t-sql

我已经研究出了如何在 SQL Server 2005 中使用 PIVOT 从表中旋转一行,但是,我不喜欢这种方法,因为我必须对列(货币代码)进行硬编码,并且我希望有 Pivot动态选择列。

作为示例,假设您有下表(称为 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

硬编码的 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 

所以简单的部分已经完成(SELECT * FROM dbo.GetTableColumnNames('OrderCash',2)),我遇到的问题是将这个带有列名的“动态”表插入数据透视表?

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

最佳答案

我最近做了太多这样的动态查询......(我的专栏按客户每月移动)。这是一种方法——无需测试,无需调试,可能存在一些需要解决的错误:

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

关于sql-server-2005 - 动态 SQL Server 2005 枢轴,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7555968/

相关文章:

c# - 与 SQL Server 的初始连接速度很慢。为什么?

sql-server-2005 - CLR存储过程:SqlContext.Pipe.SendResultsStart/SendResultsRow/SendResultsEnd的替代方法?

sql-server-2005 - 具有复杂条件的 Row_Number

sql-server - 如何使用 BCP 或 Sql Server Management Studio 从 Sql Server 中获取 BLOB 数据?

SQL 限制 "WHERE X IN (...)"

xml - 带有 XML 的 SQL Server 2005 中的层次结构

sql - 查找公制格式的日期时间值之间的时间

sql - 对于具有较大 Id 的行,是否使用 DBCC CHECKIDENT 安全重置主键

t-sql - 从连接表中选择记录(如果存在)

sql - sql 中的 xml select 出现问题 - 似乎无法按正确的顺序组织多个节点