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ą