Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Non è possibile ruotare la tabella con la mia query?

Solo per espandere le altre risposte, la funzione PIVOT richiede un qualche tipo di aggregazione. Poiché il valore che vuoi convertire da una riga in una colonna è una stringa, sei limitato all'uso di max() o min() funzione aggregata.

Mentre @Muhammed Ali's la risposta funzionerà quando hai un unico AttributeName /AttributeValue coppia, se hai più coppie per ogni ID , quindi restituirai solo il max o min valore.

Ad esempio, se i tuoi dati di esempio sono:

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

Anche se hai più righe per la combinazione di A1 e Atr1 , le altre query restituiscono solo max(attributevalue) :

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

Immagino che tu voglia effettivamente restituire tutte le combinazioni. Suggerisco di espandere la tua query per includere la funzione di finestra, row_number() nella tua domanda. Questa query genera un valore univoco che verrà quindi incluso nell'aspetto di raggruppamento del PIVOT e ti consentirà di restituire più di una riga per ciascun ID.

Aggiungendo il row_number() , la query sarà simile alla seguente:

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;

Vedi SQL Fiddle con demo . Otterrai un risultato che restituisce tutte le righe:

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

Se hai difficoltà a comprendere il concetto di PIVOT, ti suggerirei di utilizzare una combinazione di una funzione aggregata con un'espressione CASE per ottenere il risultato. Puoi quindi vedere il raggruppamento della sequenza/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

Vedi SQL Fiddle con demo