Reputation: 1193
I have worked out how to pivot a row from a table using PIVOT in SQL Server 2005, however, I dont like the method as I have had to hard code the columns (Currency Codes) and I would like to have the Pivot select the columns dynamically.
As an Example, imagine you have the following table (called 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
The hard-coded Pivot statement is:
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
This would return the following required table:
OrderID Ticker Position
42 CADGBP CURNCY 233.23
42 EURGBP CURNCY 552.25
42 GBPGBP CURNCY -9232
42 USDGBP CURNCY -4762
The problem arrises further down the road when someone tells me I need to have AUD as a new currency in the table?
FYI, I have a table-valued function that returns all the column names as a table:
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
So the easy bit has been done (SELECT * FROM dbo.GetTableColumnNames('OrderCash',2)), the problem I am having is inserting this 'dynamic' table with the column names into the Pivot?
Any help would be much appreciated. Many thanks Bertie.
Upvotes: 2
Views: 941
Reputation: 40359
I've done a few too many of these dynamic queries of late... (my columns shift by client by month). Here's one way to do it--no testing, no debugging, there might be a few bugs to iron out:
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
Upvotes: 3