Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Nie możesz przestawić tabeli z moim zapytaniem?

Aby rozwinąć inne odpowiedzi, funkcja PIVOT wymaga pewnego rodzaju agregacji. Ponieważ wartość, którą chcesz przekonwertować z wiersza na kolumnę, jest ciągiem, możesz użyć funkcji max() lub min() funkcja agregująca.

Podczas gdy @Muhammed Ali odpowiedź zadziała, gdy masz pojedynczy AttributeName /AttributeValue sparuj, jeśli masz wiele par dla każdego ID , zwrócisz tylko max lub min wartość.

Na przykład, jeśli Twoje przykładowe dane to:

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');

Nawet jeśli masz wiele wierszy dla kombinacji A1 i Atr1 , pozostałe zapytania zwracają tylko max(attributevalue) :

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

Przypuszczam, że chciałbyś zwrócić wszystkie kombinacje. Proponuję rozszerzyć zapytanie o funkcję okienkowania, row_number() w zapytaniu. To zapytanie generuje unikalną wartość, która zostanie następnie uwzględniona w aspekcie grupowania elementu PIVOT i umożliwi zwrócenie więcej niż jednego wiersza dla każdego identyfikatora.

Dodając row_number() , zapytanie będzie podobne do następującego:

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;

Zobacz SQL Fiddle z wersją demonstracyjną . Otrzymasz wynik, który zwróci wszystkie wiersze:

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

Jeśli masz problem ze zrozumieniem koncepcji PIVOT, sugerowałbym, aby przyjrzeć się kombinacji funkcji agregującej z wyrażeniem CASE, aby uzyskać wynik. Możesz wtedy zobaczyć grupowanie sekwencji/id:

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

Zobacz SQL Fiddle z wersją demonstracyjną



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak przechwycić dane wyjściowe instrukcji DBCC w pokusie?

  2. Dlaczego nie mogę użyć aliasu w instrukcji DELETE?

  3. 5 szybkich przydatnych wskazówek dla administratorów baz danych SQL Server Production

  4. trzeba uzyskać dane pogrupowane według groupid

  5. java.sql.SQLException:SQL Server w wersji 8 nie jest obsługiwany przez ten sterownik. Stan SQL =08S01, kod błędu =0