0

I have a table

name    value1  value2  value3
-------------------------------
abc     100     200     200
abc1    101     201     NULL
abc2    NULL    NULL    200
abc3    NULL    NULL    200
abc4    NULL    NULL    200

Expected result

abc     abc1    abc2   abc3  abc4
-----------------------------------
100     101     NULL    NULL  NULL
200     201     NULL    NULL  NULL
200     NULL    200     200   200               

Please suggest how to convert this dynamically using pivot or any other method in T-SQL

3
  • Which dbms are you using? Commented Apr 8, 2020 at 8:01
  • ms sql server 2016 Commented Apr 8, 2020 at 8:04
  • 1
    Does this answer your question? Simple way to transpose columns and rows in SQL? Commented Apr 8, 2020 at 8:26

1 Answer 1

3

Just make UNPIVOT, then PIVOT:

DROP TABLE dbo.DataSource

CREATE TABLE dbo.DataSource 
(
    [name] VARCHAR(10)
   ,[value1] INT
   ,[value2] INT
   ,[value3] INT
);

INSERT INTO dbo.DataSource ([name], [value1], [value2], [value3])
VALUES ('abc', 100, 200, 200)
      ,('abc1', 101, 201, NULL)
      ,('abc2', NULL, NULL, 200)
      ,('abc3', NULL, NULL, 200)
      ,('abc4', NULL, NULL, 200);

SELECT [abc], [abc1], [abc2], [abc3], [abc4]
FROM dbo.DataSource DS
UNPIVOT
(
    [value] FOR [column] IN ([value1], [value2], [value3])
) UNPVT
PIVOT
(
    MAX([value]) FOR [name] IN ([abc], [abc1], [abc2], [abc3], [abc4])
) PVT;

enter image description here

The dynamic part of this query are the unpivot and the pivot columns. So, if you need a dynamic solution just use the code below:

DECLARE @DynamictSQLStatement NVARCHAR(MAX)
       ,@UnpivotColumns NVARCHAR(MAX)
       ,@PivotColumns NVARCHAR(MAX);

SET @PivotColumns = STUFF
(
    (
        SELECT DISTINCT ',' + QUOTENAME([name])
        FROM dbo.DataSource
        ORDER BY ',' + QUOTENAME([name])
        FOR XML PATH(''), TYPE
    ).value('.', 'NVARCHAR(MAX)')
    ,1
    ,1
    ,''
);

SET @UnpivotColumns = STUFF
(
    (
        SELECT DISTINCT ',' + QUOTENAME([name])
        FROM sys.columns
        WHERE [object_id] = OBJECT_ID('dbo.DataSource ')
            AND [name] <> 'name'
        FOR XML PATH(''), TYPE
    ).value('.', 'NVARCHAR(MAX)')
    ,1
    ,1
    ,''
);

SET @DynamictSQLStatement = N'SELECT ' + @PivotColumns + '
FROM dbo.DataSource DS
UNPIVOT
(
    [value] FOR [column] IN (' + @UnpivotColumns + ')
) UNPVT
PIVOT
(
    MAX([value]) FOR [name] IN (' + @PivotColumns + ')
) PVT;'

EXEC sp_executesql @DynamictSQLStatement;

For the UNPIVOT columns we are using system view and for the PIVOT we need to touch the real data.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.