2009-11-05 4 views
7

Lassen Sie uns sagen, dass ich ein paar Daten, entweder in einer SQL Server 2008-Tabelle oder eine [Tabelle] -typed Variable:Mit PIVOT in SQL Server 2008

author_id  review_id  question_id  answer_id 
88540   99001   1    719 
88540   99001   2    720 
88540   99001   3    721 
88540   99001   4    722 
88540   99001   5    723 
36414   24336   1    302 
36414   24336   2    303 
36414   24336   3    304 
36414   24336   4    305 
36414   24336   5    306 

ich die Daten als Ergebnismenge abrufen möchten, die sieht wie folgt aus:

author_id  review_id  1  2  3  4  5 
88540   99001   719 720 721 722 723 
36414   24336   302 303 304 305 306 

ich die PIVOT-Operator vermuten ist, was ich brauche (nach this post, sowieso), aber ich kann nicht herausfinden, wie um zu beginnen, vor allem, wenn die Anzahl der question_id Reihen in Der Tisch kann variieren. Im obigen Beispiel ist es 5, aber in einer anderen Abfrage könnte die Tabelle mit 7 verschiedenen Fragen gefüllt sein.

Antwort

9

Eigentlich wäre es besser, wenn Sie das im Client tun. Angenommen, Sie verwenden Reporting Services, rufen Sie die Daten gemäß Ihrer ersten Ergebnismenge ab und zeigen sie mithilfe einer Matrix an, mit author_id und review_id in der Zeilengruppe, question_id in der Spaltengruppe und MAX (answer_id) in der Mitte.

Eine Abfrage ist machbar, aber Sie benötigen jetzt dynamisches SQL.

... so etwas wie:

DECLARE @QuestionList nvarchar(max); 
SELECT @QuestionList = STUFF(
(SELECT ', ' + quotename(question_id) 
FROM YourTable 
GROUP BY question_id 
ORDER BY question_id 
FOR XML PATH('')) 
, 1, 2, ''); 

DECLARE @qry nvarchar(max); 
SET @qry = ' 
SELECT author_id, review_id, ' + @QuestionList + 
FROM (SELECT author_id, review_id, question_id, answer_id 
     FROM YourTable 
    ) 
PIVOT 
(MAX(AnswerID) FOR question_id IN (' + @QuestionList + ')) pvt 
ORDER BY author_id, review_id;'; 

exec sp_executesql @qry; 
+0

Dies scheint zu sein, was ich brauche. Ich werde es versuchen und zurückmelden - danke! –

+1

Bitte beachten Sie die Unterabfrage. Wenn Sie nur "SELECT * FROM YourTable" verwenden, wirken sich alle anderen beteiligten Spalten auf die implizite Gruppierung aus, die die PIVOT-Funktion bereitstellt. Und wenn Sie irgendwelche Fehler haben, kommentieren Sie die 'exec' Zeile und ersetzen sie durch' select @ qry' –

+0

Ich benutze nie mehr [SELECT *] - ich gebe immer explizit die Spalten an, auf die ich zugreife - so wird es nicht sein ein Problem. Und ja, ich benutzte [select @qry] für eine Weile, damit ich die generierte SQL-Anweisung sehen/debuggen konnte, bevor sie ausgeführt wurde. Ihr Code funktionierte wie versprochen - vielen Dank für Ihre Hilfe! –

0
select * 
from @t pivot 
(
    max(answer_id) for question_id in ([1],[2],[3],[4],[5]) 
) pivotT 

Der einzige Weg, um die Liste ([1], [2], [3], [4], [5]) zu variieren, wäre diese Abfrage in einer Zeichenfolge zu bauen (dynamisch) und dann ausgeführt werden es.

3

Here Sie haben großes Beispiel und Erklärung.

In Ihrem Fall würde es so sein:

SELECT author_id, review_id, [1], [2], [3], [4], [5] 
FROM 
    (
     SELECT author_id, review_id, question_id, answer_id 
     FROM the_table 
    ) up 
PIVOT (MAX(answer_id) FOR question_id IN ([1],[2],[3],[4],[5])) AS pvt 
0

Siehe this answer

Grundsätzlich Sie die Daten vorab inspizieren die Spalten zu bekommen und dann generieren dynamisch die SQL die dynamische Pivot-Liste. Es gibt wirklich keinen nicht-dynamischen Weg, weil die Definition der Spalten in der Menge, die Sie zurückgeben wollen, nicht festgelegt ist.

2
SELECT author_id, review_id, [1], [2], [3], [4], [5] 
FROM 
    (
     SELECT author_id, review_id, question_id, answer_id 
     FROM the_table 
    ) up 
PIVOT (MAX(answer_id) FOR