Abfrage zur Erhebung der Umfrage Zusammenfassung (PIVOT)

Nehmen wir an, ich habe zwei Tische:

Question (Id, Text) Answer (Value, QuestionId, Guid) 

Spalte Guid Gruppen Antworten von der gleichen Person.

Ich brauche eine Abfrage, um solche Ergebnisse zu erzielen:

 'Question 1' | 'Question 2' 4 | 3 1 | NULL NULL | 5 2 | 6 9 | NULL 

Fragentexte werden in Spaltenüberschriften umgewandelt und antwortet Werte in Zeilen. Antworten werden von Guid gruppiert, also gibt es Antworten von einer Person in einer Reihe. Wenn eine Person keine Frage beantwortet hat, wird NULL zurückgegeben.

Anzahl der Fragen können variieren.

data zur Herstellung von Stichprobenergebnissen:

  Question Id | Text 1 | Question 1 2 | Question 2 Answer Value | QuestionId | Guid 4 | 1 | AAA 3 | 2 | AAA 1 | 1 | BBB 5 | 2 | CCC 2 | 1 | DDD 6 | 2 | DDD 9 | 1 | EEE 

Können Sie mir bitte mit einer Abfrage helfen, die Ergebnisse zu erzielen?

   

Da Sie eine unbekannte Anzahl von Fragen haben, dann müssen Sie dynamische SQL verwenden, um dies zu PIVOT :

 DECLARE @colsFinal AS NVARCHAR(MAX), @colsPivot AS NVARCHAR(MAX), @query AS NVARCHAR(MAX) select @colsFinal = STUFF((SELECT distinct ',' + QUOTENAME(Id) + ' as Question_'+ cast(Id as varchar(10)) from question FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'') select @colsPivot = STUFF((SELECT distinct ',' + QUOTENAME(Id) from question FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'') set @query = 'SELECT ' + @colsFinal + ' from ( select questionid, value, guid from question q left join value v on q.id = v.questionid ) x pivot ( min(value) for questionid in (' + @colsPivot + ') ) p ' execute(@query) 

Siehe SQL Fiddle mit Demo

Wenn du eine bekannte Anzahl von Spalten hättest, dann könntest du die Werte für den PIVOT hart kodieren (siehe SQL Fiddle With Demo ):

 select [1] as Question1, [2] as Question2 from ( select questionid, value, guid from question q left join value v on q.id = v.questionid ) x pivot ( max(value) for questionid in ([1], [2]) ) p 

Oder Sie können eine Aggregatfunktion mit einem CASE (siehe SQL Fiddle With Demo ):

 select max(case when q.id = 1 then v.value end) Question1, max(case when q.id = 2 then v.value end) Question2 from question q left join value v on q.id = v.questionid group by guid 

Wenn du die Question Numbers nicht hart codierst, dann bist du auf die Verwendung von dynamischem SQL beschränkt, um die Frageliste aufzubuild.

SQL server dynamische PIVOT-Abfrage?

Für spezifische Fragen, wenn Sie ihre Texte kennen, siehe Beispiel unten

 create table Question(id int, text varchar(100)); insert Question select 1, 'Question 1' union all select 2, 'The 2nd'; create table Answer( value int, questionid int, guid varchar(10)); insert Answer select 4 , 1 , 'AAA' union all select 3 , 2 , 'AAA' union all select 1 , 1 , 'BBB' union all select 5 , 2 , 'CCC' union all select 2 , 1 , 'DDD' union all select 6 , 2 , 'DDD' union all select 9 , 1 , 'EEE'; GO select guid, [Question 1], [The 2nd] from ( select guid, text, value from Answer A join Question Q on A.questionid=q.id) p pivot (max(value) for text in ([Question 1], [The 2nd])) v