Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Não é possível tabela dinâmica com minha consulta?


Apenas para expandir as outras respostas, a função PIVOT requer algum tipo de agregação. Como o valor que você deseja converter de uma linha em uma coluna é uma string, você está limitado a usar o max() ou min() função agregada.

Enquanto @Muhammed Ali resposta funcionará quando você tiver um único AttributeName /AttributeValue par, se você tiver vários pares para cada ID , você retornará apenas o valor max ou min valor.

Por exemplo, se seus dados de amostra forem:
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');

Mesmo que você tenha várias linhas para a combinação de A1 e Atr1 , as outras consultas estão retornando apenas o max(attributevalue) :
| ID | ATR1 | ATR2 | ATR3 |
|----|------|------|------|
| A1 | A1V4 | A1V2 | A1V3 |
| A2 | A2V1 | A2V2 | A3V3 |

Eu acho que você realmente gostaria de retornar todas as combinações. Sugiro expandir sua consulta para incluir a função de janela, row_number() em sua consulta. Essa consulta gera um valor exclusivo que será incluído no aspecto de agrupamento do PIVOT e permitirá que você retorne mais de uma linha para cada ID.

Adicionando o row_number() , a consulta será semelhante à seguinte:
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 with Demo . Você obterá um resultado que retorna todas as linhas:
| ID | ATR1 |   ATR2 |   ATR3 |
|----|------|--------|--------|
| A1 | A1V1 |   A1V2 |   A1V3 |
| A1 | A1V4 | (null) | (null) |
| A2 | A2V1 |   A2V2 |   A3V3 |

Se você está tendo problemas para entender o conceito de PIVOT, sugiro que use uma combinação de uma função de agregação com uma expressão CASE para obter o resultado. Você pode então ver o agrupamento da sequência/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 with Demo