ellickakudy rajeesh
ellickakudy rajeesh

Reputation: 747

SQL Pivot function

Please help me to write a select query using to pivot my table as below

My table structure

enter image description here

And required result structure

StoryLineID PlotID StoryLine Question

 1          1      01      question 1
 1          1      02      question 2
 1          1      03      question 3
 1          1      04      question 4
 1          1      05      question 5

Upvotes: 3

Views: 93

Answers (2)

Devart
Devart

Reputation: 121932

Try this one -

DECLARE @temp TABLE
(
      ID INT
    , PlotID INT
    , StoryLine_01 VARCHAR(10)
    , StoryLine_02 VARCHAR(10)
    , StoryLine_03 VARCHAR(10)
    , StoryLine_04 VARCHAR(10)
    , StoryLine_05 VARCHAR(10)
)

INSERT INTO @temp
VALUES 
    (1, 3, 'Q1', 'Q2', 'Q3', 'Q4', 'Q5'),
    (2, 4, 'Q1', 'Q2', 'Q3', 'Q4', 'Q5')

SELECT 
      ID
    , PlotID
    , StoryLine = RIGHT(StoryLine, 2)
    , Question
FROM @temp
UNPIVOT 
(
    Question FOR StoryLine IN (
        StoryLine_01, StoryLine_02, 
        StoryLine_03, StoryLine_04, 
        StoryLine_05
    )
) unpvt

Update (dynamic count of columns):

IF OBJECT_ID (N'dbo.temp') IS NOT NULL
   DROP TABLE dbo.temp

CREATE TABLE dbo.temp
(
      ID INT
    , PlotID INT              , StoryLine_01 VARCHAR(10)
    , StoryLine_02 VARCHAR(10), StoryLine_03 VARCHAR(10)
    , StoryLine_04 VARCHAR(10), StoryLine_05 VARCHAR(10)
)

INSERT INTO dbo.temp
VALUES (1, 3, 'Q1', 'Q2', 'Q3', 'Q4', 'Q5'), (2, 4, 'Q1', 'Q2', 'Q3', 'Q4', 'Q5')

DECLARE @SQL NVARCHAR(MAX)
SELECT @SQL = '
    SELECT 
          ID
        , PlotID
        , StoryLine = RIGHT(StoryLine, 2)
        , Question
    FROM dbo.temp
    UNPIVOT (
        Question FOR StoryLine IN (
            ' + STUFF((
                SELECT ', ' + name
                FROM sys.columns WITH(NOWAIT)
                WHERE [object_id] = OBJECT_ID('dbo.temp')
                    AND name LIKE 'StoryLine_%'
                FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 2, '') + 
        ')
    ) unpvt'

EXEC sys.sp_executesql @SQL

Output -

ID          PlotID      StoryLine Question
----------- ----------- --------- ----------
1           3           01        Q1
1           3           02        Q2
1           3           03        Q3
1           3           04        Q4
1           3           05        Q5
2           4           01        Q1
2           4           02        Q2
2           4           03        Q3
2           4           04        Q4
2           4           05        Q5

Upvotes: 3

roman
roman

Reputation: 117400

if number of columns is large and number of total rows is not very large, you can do this general query, so you could not to specify all column name explicitly

;with CTE1 as (
    select ID, PlotID, (select t.* for xml raw('row'), type) as Data
    from @temp as t
), CTE2 as (
    select
         C.ID, C.PlotID,
         F.C.value('local-name(.)', 'nvarchar(128)') as StoryLine,
         F.C.value('.', 'nvarchar(max)') as Question
    from CTE1 as c
        outer apply c.Data.nodes('row/@*') as F(C)
)
select
   ID, PlotID, replace(StoryLine, 'StoryLine_', '') as StoryLine, Question
from CTE2
where StoryLine like 'StoryLine[_]%'

sql fiddle demo (Thanks @Devart!)

Upvotes: 2

Related Questions