Question

I have three tables - the first contains questions with a unique ID

QID     | Question  
------------------  
1       | Question 1  
2       | Question 2  
3       | Question 3  
4       | Question 4  
5       | Question 5  

The second contains answers to those questions, the unique ID from the first table and then an ID of the record that links the answers together

QID     | Answer | Parent
-------------------------
1       | Yes    | 123
2       | No     | 123  
3       | No     | 123  
4       | Yes    | 123  
5       | Yes    | 123
1       | No     | 124
2       | Yes    | 124  
3       | No     | 124  
4       | No     | 124  
5       | No     | 124

The third contains other information about the parent

Parent     |      Parent Title
----------------------------------------
123        |      Questionnaire Sample 1
124        |      Questionnaire Sample 2

Ideally I would like to create a view that transposes or pivots the data into a more usable format, I'm thinking something along the lines of:

Parent     | Question 1     | Question 2     | Question 3     | Question 4     | Question 5
123        | Yes            | No             | No             | Yes            | Yes
124        | No             | Yes            | No             | No             | No

I found a couple of really nice threads on here that I've been working with:

Simple way to transpose columns and rows in Sql?

T-SQL Pivot/Unpivot(Transpose) Column Headers Needed as Data Rows

There was another one:

Transpose rows into columns in SQL Server 2008 R2

that I pulled the following from:

SELECT [First_Set], [Second_Set]
FROM
(
  SELECT B.ColumnName, A.Value
    , row_number() over(partition by a.Table2ID
                    order by a.Value) seq
  FROM Table_1 AS A 
  INNER JOIN Table_2 AS B 
    ON A.Table2ID = B.ID
) AS P
PIVOT
(
  min(P.Value)
  for P.ColumnName in ([First_Set], [Second_Set])
) AS PIV;

I then modified that to be:

SELECT [PARENT], [QUESTION], [ANSWER]
FROM
(
  SELECT B.PARENT_TITLE, C.QUESTION, A.ANSWER
    , row_number() over(partition by a.PARENT
                        order by a.PARENT) seq
  FROM answerTable AS A 
  INNER JOIN parentTable AS B 
    ON A.PARENT = B.PARENT
  INNER JOIN questionTable AS C 
    ON A.QID = C.QID    
) AS P
PIVOT
(
  min(P.RESULT)
  for P.PARENT in ([PARENT], [QUESTION], [ANSWER])
) AS PIV;

Which returns but still isn't as I need it.

It's not feasible for me to create new tables so ideally I'm looking for a dynamic means here, it's for reporting so a view would be easiest / best in my opinion but I am open to suggestions.

Thanks.

Was it helpful?

Solution

Here's how to do it dynamically:

create table #t1(QID int, Question char(10))
insert #t1 values
(1, 'Question 1'),  
(2, 'Question 2'),  
(3, 'Question 3'),  
(4, 'Question 4'),  
(5, 'Question 5')  

create table #t2 (QID int, Answer char(3), Parent int)
insert #t2 values 
(1,        'Yes',    123),
(2,        'No ',    123),  
(3,        'No ',    123),  
(4,        'Yes',    123),  
(5,        'Yes',    123),
(1,        'No ',    124),
(2,        'Yes',    124),  
(3,        'No ',    124),  
(4,        'No ',    124),  
(5,        'No ',    124)

declare @collist nvarchar(max)
SET @collist = stuff((select distinct ',' + QUOTENAME(Question) 
            FROM #t1 -- your table here
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')
select @collist

declare @q nvarchar(max)
set @q = '
select * 
from (
    select 
    Question, Answer, Parent
        from (
        select #t1.*, #t2.Answer, #t2.parent
        from #t1
        inner join #t2 on #t1.QID = #t2.QID
    ) as x
) as source
pivot (
    max(Answer)
    for Question in (' + @collist + ')
) as pvt
'

exec (@q)

OTHER TIPS

Another way of solving your question -

declare @dynamicSQL varchar(max) = ''
declare @pivotList varchar(max) = ''
declare @uniqueQuestions table ([Question] varchar(50) )
insert into @uniqueQuestions
select distinct [Question] from Questions 
select @pivotList = @pivotList + '[' + Question + '],'  from @uniqueQuestions
set @pivotList = SUBSTRING(@pivotList, 0, LEN(@pivotList))
set @dynamicSQL = 
'select *
from
(
select Parent, Question, Answer
from Questions as q
left join Answers as a
on q.QID = a.QID
) as src
pivot(
max(answer)
for Question in (' + @pivotList + ')' + 
')as pvt'
exec(@dynamicSQL)

Thanks to this post for making it happen - Convert multiple rows into one with comma as separator

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top