add dynamic placeholder columns to dynamically pivoted data

馋奶兔 提交于 2020-01-07 05:36:11

问题


This questions follows on from this one. The following Sql work fine:

IF OBJECT_ID('tempdb..#Source') IS NOT NULL DROP TABLE #Source
IF OBJECT_ID('tempdb..#Aim') IS NOT NULL DROP TABLE #Aim

CREATE TABLE #Source
(
    ColumnName NVARCHAR(10),
    ColumnValue NVARCHAR(10),
    Id INT
)

CREATE TABLE #Aim
(
    Id INT,
    Column1 NVARCHAR(10),
    Column2 NVARCHAR(10),
    Column3 NVARCHAR(10)
)

INSERT INTO #Source (ColumnName, ColumnValue, Id) VALUES ('Column1', 'Value1', 1);
INSERT INTO #Source (ColumnName, ColumnValue, Id) VALUES ('Column2', 'Value1', 1);
INSERT INTO #Source (ColumnName, ColumnValue, Id) VALUES ('Column1', 'Value2', 2);
INSERT INTO #Source (ColumnName, ColumnValue, Id) VALUES ('Column1', 'Value4', 3);
INSERT INTO #Source (ColumnName, ColumnValue, Id) VALUES ('Column3', 'Value1', 3);
INSERT INTO #Source (ColumnName, ColumnValue, Id) VALUES ('Column3', 'Value3', 4);

INSERT INTO #Aim (Id, Column1, Column2, Column3) VALUES (1, 'Value1', 'Value1', NULL)
INSERT INTO #Aim (Id, Column1, Column2, Column3) VALUES (2, 'Value2', NULL, NULL)
INSERT INTO #Aim (Id, Column1, Column2, Column3) VALUES (3, 'Value4', NULL, 'Value1')
INSERT INTO #Aim (Id, Column1, Column2, Column3) VALUES (4, NULL, NULL, 'Value3')

DECLARE @col_list VARCHAR(max) = (SELECT Quotename(ColumnName) + ','
   FROM   #Source
   GROUP  BY ColumnName
   ORDER  BY ColumnName
   FOR xml path('')) -- To create the dynamic column list 

SET @col_list = LEFT(@col_list, Len(@col_list) - 1) -- To remove the leading comma 

DECLARE @sql NVARCHAR(max)

SELECT @sql = 'select * from #Source
pivot (max(ColumnValue) for ColumnName in ('
              + @col_list + '))pv'

EXEC Sp_executesql @sql  -- Execute the dynamic sql

The challenge is that I want to add dummy column if there are less than n columns. So for n = 5 I would like to achieve this as output:

Id  Column1 Column2 Column3 Dummy4  Dummy5
1   Value1  Value1  NULL    NULL    NULL
2   Value2  NULL    NULL    NULL    NULL
3   Value4  NULL    Value1  NULL    NULL
4   NULL    NULL    Value3  NULL    NULL

Is this possible ideally with n as a variable?


回答1:


Here is one way

DECLARE @n INT = 5
DECLARE @cnt INT = (SELECT Count(DISTINCT ColumnName)
   FROM   #Source)
DECLARE @col_list VARCHAR(max) = (SELECT Quotename(ColumnName) + ','
   FROM   #Source
   GROUP  BY ColumnName
   ORDER  BY ColumnName
   FOR xml path('')) -- To create the dynamic column list 
SET @col_list = LEFT(@col_list, Len(@col_list) - 1)

WHILE @cnt + 1 <= @n -- To create the dummy list based on existing count 
  BEGIN
      SET @col_list+=',[dummy' + Cast(@cnt + 1 AS VARCHAR(100)) + ']'
      SET @cnt = @cnt + 1
  END

DECLARE @sql NVARCHAR(max)

SELECT @sql = 'select * from #Source
    pivot (max(ColumnValue) for ColumnName in ('
              + @col_list + '))pv'

--PRINT @sql

EXEC Sp_executesql @sql 

Result:

╔════╦═════════╦═════════╦═════════╦════════╦════════╗
║ Id ║ Column1 ║ Column2 ║ Column3 ║ dummy4 ║ dummy5 ║
╠════╬═════════╬═════════╬═════════╬════════╬════════╣
║  1 ║ Value1  ║ Value1  ║ NULL    ║ NULL   ║ NULL   ║
║  2 ║ Value2  ║ NULL    ║ NULL    ║ NULL   ║ NULL   ║
║  3 ║ Value4  ║ NULL    ║ Value1  ║ NULL   ║ NULL   ║
║  4 ║ NULL    ║ NULL    ║ Value3  ║ NULL   ║ NULL   ║
╚════╩═════════╩═════════╩═════════╩════════╩════════╝


来源:https://stackoverflow.com/questions/35803654/add-dynamic-placeholder-columns-to-dynamically-pivoted-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!