Reputation: 747
Please help me to write a select query using to pivot my table as below
My table structure
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
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
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