sql >> Base de Datos >  >> RDS >> Sqlserver

¿No puede la tabla dinámica con mi consulta?

Solo para ampliar las otras respuestas, la función PIVOT requiere algún tipo de agregación. Dado que el valor que desea convertir de una fila a una columna es una cadena, entonces está limitado a usar el max() o min() función agregada.

Mientras que de @Muhammed Ali la respuesta funcionará cuando tenga un solo AttributeName /AttributeValue par, si tiene varios pares para cada ID , solo devolverá el max o min valor.

Por ejemplo, si sus datos de muestra son:

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

Aunque tenga varias filas para la combinación de A1 y Atr1 , las otras consultas solo devuelven el max(attributevalue) :

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

Supongo que en realidad querrías devolver todas las combinaciones. Sugiero expandir su consulta para incluir la función de ventana, row_number() en tu consulta Esta consulta genera un valor único que luego se incluirá en el aspecto de agrupación del PIVOT y le permitirá devolver más de una fila para cada ID.

Agregando el row_number() , la consulta será similar a la siguiente:

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;

Consulte SQL Fiddle con demostración . Obtendrá un resultado que devuelve todas las filas:

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

Si tiene problemas para comprender el concepto de PIVOT, le sugiero que utilice una combinación de una función agregada con una expresión CASE para obtener el resultado. A continuación, puede ver la agrupación de la secuencia/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

Consulte SQL Fiddle con demostración