Bare for at udvide med de andre svar, kræver PIVOT-funktionen en eller anden form for aggregering. Da den værdi, du vil konvertere fra en række til en kolonne, er en streng, er du begrænset til at bruge enten max()
eller min()
aggregeret funktion.
Mens @Muhammed Ali's
svaret fungerer, når du har et enkelt AttributeName
/AttributeValue
par, hvis du har flere par for hvert ID
, så returnerer du kun enten max
eller min
værdi.
For eksempel hvis dine eksempeldata er:
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');
Selvom du har flere rækker for kombinationen af A1
og Atr1
, returnerer de andre forespørgsler kun max(attributevalue)
:
| ID | ATR1 | ATR2 | ATR3 |
|----|------|------|------|
| A1 | A1V4 | A1V2 | A1V3 |
| A2 | A2V1 | A2V2 | A3V3 |
Jeg vil gætte på, at du faktisk ønsker at returnere alle kombinationerne. Jeg foreslår, at du udvider din forespørgsel til at inkludere vinduesfunktionen, row_number()
i din forespørgsel. Denne forespørgsel genererer en unik værdi, som derefter vil blive inkluderet i grupperingsaspektet af PIVOT og vil tillade dig at returnere mere end én række for hvert ID.
Ved at tilføje row_number()
, vil forespørgslen ligne følgende:
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;
Se SQL Fiddle with Demo . Du får et resultat, der returnerer alle rækker:
| ID | ATR1 | ATR2 | ATR3 |
|----|------|--------|--------|
| A1 | A1V1 | A1V2 | A1V3 |
| A1 | A1V4 | (null) | (null) |
| A2 | A2V1 | A2V2 | A3V3 |
Hvis du har problemer med at forstå begrebet PIVOT, så vil jeg foreslå at se på at bruge en kombination af en aggregeret funktion med et CASE-udtryk for at få resultatet. Du kan derefter se grupperingen af sekvensen/id'et:
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