Bara för att utöka de andra svaren kräver PIVOT-funktionen någon typ av aggregering. Eftersom värdet som du vill konvertera från en rad till en kolumn är en sträng, är du begränsad till att använda antingen max()
eller min()
aggregerad funktion.
Medan @Muhammed Ali's
svaret fungerar när du har ett enda AttributeName
/AttributeValue
par, om du har flera par för varje ID
, då returnerar du bara antingen max
eller min
värde.
Till exempel om din exempeldata är:
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');
Även om du har flera rader för kombinationen av A1
och Atr1
, de andra frågorna returnerar bara max(attributevalue)
:
| ID | ATR1 | ATR2 | ATR3 |
|----|------|------|------|
| A1 | A1V4 | A1V2 | A1V3 |
| A2 | A2V1 | A2V2 | A3V3 |
Jag skulle gissa att du faktiskt skulle vilja returnera alla kombinationer. Jag föreslår att du utökar din fråga till att inkludera fönsterfunktionen, row_number()
i din fråga. Den här frågan genererar ett unikt värde som sedan inkluderas i grupperingsaspekten av PIVOT och gör att du kan returnera mer än en rad för varje ID.
Genom att lägga till row_number()
, kommer frågan att likna följande:
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-fiol med demo . Du får ett resultat som returnerar alla rader:
| ID | ATR1 | ATR2 | ATR3 |
|----|------|--------|--------|
| A1 | A1V1 | A1V2 | A1V3 |
| A1 | A1V4 | (null) | (null) |
| A2 | A2V1 | A2V2 | A3V3 |
Om du har problem med att förstå konceptet PIVOT, skulle jag föreslå att du använder en kombination av en aggregerad funktion med ett CASE-uttryck för att få resultatet. Du kan sedan se grupperingen av sekvensen/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