Sql server 2005 动态SQLServer2005Pivot
我已经解决了如何在SQLServer2005中使用pivot从表中透视一行,但是,我不喜欢这种方法,因为我必须硬编码列货币代码,我希望pivot动态选择列 例如,假设您有一个名为OrderCash的下表: 硬编码的Pivot语句是: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,
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