Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Kann mit meiner Abfrage keine Pivot-Tabelle erstellen?

Um die anderen Antworten zu erweitern, erfordert die PIVOT-Funktion eine Art Aggregation. Da der Wert, den Sie von einer Zeile in eine Spalte umwandeln möchten, ein String ist, können Sie entweder max() verwenden oder min() Aggregatfunktion.

Während @Muhammed Alis Antwort funktioniert, wenn Sie einen einzelnen AttributeName haben /AttributeValue Paar, wenn Sie mehrere Paare für jede ID haben , dann geben Sie entweder nur den max zurück oder min Wert.

Beispiel:Ihre Beispieldaten sind:

INSERT INTO @MyTable VALUES ('A1', 'Atr1', 'A1V1');
INSERT INTO @MyTable VALUES ('A1', 'Atr1', 'A1V4');
INSERT INTO @MyTable VALUES ('A1', 'Atr2', 'A1V2');
INSERT INTO @MyTable VALUES ('A1', 'Atr3', 'A1V3');
INSERT INTO @MyTable VALUES ('A2', 'Atr1', 'A2V1');
INSERT INTO @MyTable VALUES ('A2', 'Atr2', 'A2V2');
INSERT INTO @MyTable VALUES ('A2', 'Atr3', 'A3V3');

Obwohl Sie mehrere Zeilen für die Kombination von A1 haben und Atr1 , die anderen Abfragen geben nur den max(attributevalue) zurück :

| ID | ATR1 | ATR2 | ATR3 |
|----|------|------|------|
| A1 | A1V4 | A1V2 | A1V3 |
| A2 | A2V1 | A2V2 | A3V3 |

Ich würde vermuten, dass Sie tatsächlich alle Kombinationen zurückgeben möchten. Ich schlage vor, Ihre Abfrage um die Windowing-Funktion row_number() zu erweitern in Ihrer Anfrage. Diese Abfrage generiert einen eindeutigen Wert, der dann in den Gruppierungsaspekt des PIVOT aufgenommen wird und es Ihnen ermöglicht, mehr als eine Zeile für jede ID zurückzugeben.

Durch Hinzufügen der row_number() , sieht die Abfrage wie folgt aus:

SELECT Id, [Atr1], [Atr2],[Atr3]
FROM
( 
  SELECT ID, AttributeName, AttributeValue,
    row_number() over(partition by id, attributename
                      order by attributevalue) seq
  FROM @MyTable
) AS SourceTable 
PIVOT 
(
    max(AttributeValue)
    FOR AttributeName IN ([ATR1], [ATR2], [ATR3])
) AS pvt
order by id;

Siehe SQL Fiddle mit Demo . Sie erhalten ein Ergebnis, das alle Zeilen zurückgibt:

| ID | ATR1 |   ATR2 |   ATR3 |
|----|------|--------|--------|
| A1 | A1V1 |   A1V2 |   A1V3 |
| A1 | A1V4 | (null) | (null) |
| A2 | A2V1 |   A2V2 |   A3V3 |

Wenn Sie Probleme haben, das Konzept von PIVOT zu verstehen, würde ich vorschlagen, eine Kombination aus einer Aggregatfunktion mit einem CASE-Ausdruck zu verwenden, um das Ergebnis zu erhalten. Sie können dann die Gruppierung der Sequenz/ID sehen:

SELECT Id, 
  max(case when attributename = 'Atr1' then attributevalue end) Atr1,
  max(case when attributename = 'Atr2' then attributevalue end) Atr2,
  max(case when attributename = 'Atr3' then attributevalue end) Atr3
FROM
( 
  SELECT ID, AttributeName, AttributeValue,
    row_number() over(partition by id, attributename
                      order by attributevalue) seq
  FROM @MyTable
) AS SourceTable 
group by id, seq

Siehe SQL Fiddle mit Demo