Fui encarregado de criar um meio de traduzir os seguintes dados:
date category amount
1/1/2012 ABC 1000.00
2/1/2012 DEF 500.00
2/1/2012 GHI 800.00
2/10/2012 DEF 700.00
3/1/2012 ABC 1100.00
no seguinte:
date ABC DEF GHI
1/1/2012 1000.00
2/1/2012 500.00
2/1/2012 800.00
2/10/2012 700.00
3/1/2012 1100.00
Os pontos em branco podem ser NULLs ou espaços em branco, ou é bom, e as categorias precisariam ser dinâmicas. Outra ressalva possível é que executaremos a consulta em uma capacidade limitada, o que significa que as tabelas temporárias estão fora. Eu tentei pesquisar e consegui, PIVOT
mas como nunca o usei antes, realmente não o entendo, apesar dos meus melhores esforços para descobrir. Alguém pode me apontar na direção certa?
sql
sql-server
tsql
pivot
Sean Cunningham
fonte
fonte
Respostas:
PIVOT SQL dinâmico:
Resultados:
fonte
@cols
poderá removerDISTINCT
e usarGROUP BY
eORDER BY
quando receber a lista@cols
.PIVOT SQL dinâmico
Abordagem diferente para criar string de colunas
Resultado
fonte
Sei que essa pergunta é mais antiga, mas estava procurando as respostas e pensei que poderia expandir a parte "dinâmica" do problema e possivelmente ajudar alguém.
Antes de mais, criei esta solução para resolver um problema que alguns colegas de trabalho estavam tendo com conjuntos de dados grandes e inconstantes que precisavam ser rapidamente dinamizados.
Esta solução requer a criação de um procedimento armazenado; portanto, se isso estiver fora de questão para suas necessidades, pare de ler agora.
Este procedimento incluirá as variáveis-chave de uma instrução dinâmica para criar dinamicamente instruções dinâmicas para tabelas, nomes de colunas e agregados variados. A coluna Estática é usada como a coluna agrupar por / identidade para o pivô (isso pode ser retirado do código, se não for necessário, mas é bastante comum nas instruções de pivô e era necessário para resolver o problema original), a coluna pivô é onde o os nomes das colunas resultantes finais serão gerados e a coluna de valor é à qual o agregado será aplicado. O parâmetro Table é o nome da tabela, incluindo o esquema (schema.tablename). Essa parte do código pode usar um pouco de amor, porque não é tão limpa quanto eu gostaria que fosse. Funcionou para mim porque meu uso não era público e a injeção de sql não era uma preocupação.
Vamos começar com o código para criar o procedimento armazenado. Este código deve funcionar em todas as versões do SSMS 2005 e acima, mas não o testei em 2005 ou 2016, mas não consigo ver por que não funcionaria.
Em seguida, prepararemos nossos dados para o exemplo. Peguei o exemplo de dados da resposta aceita com a adição de alguns elementos de dados para usar nessa prova de conceito para mostrar os resultados variados da alteração agregada.
Os exemplos a seguir mostram as instruções de execução variadas, mostrando os agregados variados como um exemplo simples. Não optei por alterar as colunas estática, dinâmica e de valor para manter o exemplo simples. Você deve apenas copiar e colar o código para começar a mexer nele sozinho
Esta execução retorna os seguintes conjuntos de dados, respectivamente.
fonte
Versão atualizada para o SQL Server 2017 usando a função STRING_AGG para construir a lista de colunas dinâmicas:
fonte
Você pode conseguir isso usando o TSQL dinâmico (lembre-se de usar QUOTENAME para evitar ataques de injeção de SQL):
Pivôs com colunas dinâmicas no SQL Server 2005
SQL Server - Tabela dinâmica PIVOT - Injeção de SQL
Referência obrigatória à maldição e bênçãos do SQL dinâmico
fonte
QUOTENAME
somente ajuda a ataques de injeção SQL se você estiver aceitando @tableName como parâmetro de um usuário e anexando-o a uma consulta comoSET @sql = 'SELECT * FROM ' + @tableName;
. Você pode criar várias seqüências de caracteres dinâmicas e vulneráveis em SQL eQUOTENAME
não fará uma lambida para ajudá-lo.Minha solução está limpando os valores nulos desnecessários
fonte
O código abaixo fornece os resultados que substituem NULL a zero na saída.
Criação de tabela e inserção de dados:
Consulta para gerar os resultados exatos que também substituem NULL por zeros:
RESULTADO :
fonte