Procurando por uma solução elegante (ou qualquer) para converter colunas em linhas.
Aqui está um exemplo: Eu tenho uma tabela com o seguinte esquema:
[ID] [EntityID] [Indicator1] [Indicator2] [Indicator3] ... [Indicator150]
Aqui está o que eu quero obter como resultado:
[ID] [EntityId] [IndicatorName] [IndicatorValue]
E os valores do resultado serão:
1 1 'Indicator1' 'Value of Indicator 1 for entity 1'
2 1 'Indicator2' 'Value of Indicator 2 for entity 1'
3 1 'Indicator3' 'Value of Indicator 3 for entity 1'
4 2 'Indicator1' 'Value of Indicator 1 for entity 2'
E assim por diante..
Isso faz sentido? Você tem alguma sugestão sobre onde procurar e como fazê-lo no T-SQL?
sql
sql-server
tsql
unpivot
Sergei
fonte
fonte
Respostas:
Você pode usar a função UNPIVOT para converter as colunas em linhas:
Observe que os tipos de dados das colunas que você está desviando devem ser os mesmos, portanto, talvez você precise converter os tipos de dados antes de aplicar o desanexação.
Você também pode usar
CROSS APPLY
com UNION ALL para converter as colunas:Dependendo da sua versão do SQL Server, você pode usar o CROSS APPLY com a cláusula VALUES:
Por fim, se você tiver 150 colunas para desarticular e não desejar codificar a consulta inteira, poderá gerar a instrução sql usando SQL dinâmico:
fonte
UNPIVOT
e / vs.APPLY
, esta publicação de Brad Schulz em 2010 (e as seguintes ) é (são) linda.bem Se você tem 150 colunas, acho que UNPIVOT não é uma opção. Então você pode usar truque xml
sql fiddle demo
Você também pode escrever SQL dinâmico, mas eu gosto mais de xml - para SQL dinâmico, você precisa ter permissões para selecionar dados diretamente da tabela e isso nem sempre é uma opção.
ATUALIZAÇÃO
Como há uma grande chama nos comentários, acho que vou adicionar alguns prós e contras do xml / dynamic SQL. Vou tentar ser o mais objetivo possível e não mencionar elegância e feia. Se você tiver outros prós e contras, edite a resposta ou escreva nos comentários
contras
profissionais
inserted
edeleted
tabelas dentro do seu gatilho (não é possível com a dinâmica);fonte
Apenas para ajudar novos leitores, criei um exemplo para entender melhor a resposta da @ bluefeet sobre o UNPIVOT.
fonte
Eu precisava de uma solução para converter colunas em linhas no Microsoft SQL Server, sem saber os nomes das colunas (usadas no gatilho) e sem o sql dinâmico (o sql dinâmico é muito lento para ser usado em um gatilho).
Finalmente encontrei esta solução, que funciona bem:
Como você pode ver, converto a linha em XML (subconsulta selecione i, * para xml raw, isso converte todas as colunas em uma coluna xml)
Então, eu CRUZO APLICAR uma função a cada atributo XML desta coluna, para obter uma linha por atributo.
No geral, isso converte colunas em linhas, sem saber os nomes das colunas e sem usar sql dinâmico. É rápido o suficiente para o meu propósito.
(Edit: Acabei de ver Roman Pekar responder acima, que está fazendo o mesmo. Eu usei o gatilho sql dinâmico com cursores primeiro, que era 10 a 100 vezes mais lento que esta solução, mas talvez tenha sido causado pelo cursor, não pelo De qualquer forma, esta solução é muito simples e universal, portanto é definitivamente uma opção).
Estou deixando este comentário neste local, porque quero referenciar esta explicação no meu post sobre o gatilho de auditoria completa, que você pode encontrar aqui: https://stackoverflow.com/a/43800286/4160788
fonte
Você pode obter uma lista de tabelas com contas> 350. Você pode ver na lista de soluções da tabela como linha.
fonte
Só porque eu não vi isso mencionado.
Se houver mais de 2016, aqui está mais uma opção para dinamizar dinamicamente os dados sem realmente usar o Dynamic SQL.
Exemplo
Devoluções
fonte