I've got the following SQL to create a table:
declare @FirstColumnSPResultTable table
(
[HotelId] int,
[HotelName] nvarchar(256),
[2016 - Period 1] decimal(10,1),
[2016 - Period 2] decimal(10,1),
[2016 - Period 3] decimal(10,1),
[2016 - Period 4] decimal(10,1),
[Overall] decimal(10,1),
[#Jobs] int,
[Rank] int,
[OverallRow] bit
)
Where I have the [2016 - Period 1]
to [2016 - Period 4]
columns I would like to generate these based on a comma separated list of Period IDs that are passed into the Stored Procedure.
The PeriodID
s link to a Period
table which contains ID
and PeriodName
.
I thought about creating the table with only the HotelId
and HotelName
then looping through the periods and creating each column using a WHILE
loop and ALTER TABLE
statement, somehow using it's name retrieved in a SELECT
statement, then adding the last 4 columns to the table.
I think it is possible to do it this way but can anyone tell me a better way?
EDIT: Full Solution using dynamic sql as suggested by @ADyson:
DECLARE @Sql nvarchar(max) = '
DECLARE @FirstColumnSPResultTable table ([HotelId] int,
[HotelName] nvarchar(256),'
DECLARE @FirstPeriodIdCommaDelimListAsColumns nvarchar(max)
SET @FirstPeriodIdCommaDelimListAsColumns = STUFF
(
(
SELECT ',' + QUOTENAME(p.[PeriodName]) + ' decimal(10,1) '
FROM [dbo].[Period] p WITH(NOLOCK)
WHERE p.PeriodId IN (SELECT Value FROM dbo.fn_Split(',', @FirstPeriodIdCommaDelimListInt))
ORDER BY p.[Year], p.[PeriodName]
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,''
) + ','
SET @Sql = @Sql + @FirstPeriodIdCommaDelimListAsColumns + '
[Overall] decimal(10,1),
[#Jobs] int,
[Rank] int,
[OverallRow] bit)'
so I create the first part of the table, then use FirstPeriodIdCommaDelimListAsColumns
to store the next columns created from the periods as required. Then I finish off the table.