Crazy SQL Pergunta: Como fazer uma espécie de cruz se aplica com um pivô?
-
18-09-2019 - |
Pergunta
O cliente tem atalhos em seus dados onde eles têm um quantidade de registros no campo. Quando os analiso, preciso fabricar registros, um para cada quantidade, incrementando o "identificador" em 7 dias (porque o número representa uma data.
Exemplo: um único produto que está à venda por quatro semanas e preciso de quatro registros, um produto para cada semana.
Número do evento
Classificação
Semanas em execução
Alguns dados
2009 11 29 00
1
1
corre uma semana
2009 12 06 00
2
1
corre uma semana
2009 12 13 00
1
4
corre quatro semanas
2009 12 20 00
2
4
corre quatro semanas
De alguma forma, preciso transformar esses dados no seguinte com uma visualização (SQL Select) (tudo na mesma tabela, espaço em branco incluído para ver peças:
Número do evento + classificação
Alguns dados
2009 11 29 01
corre por uma semana Uma semana assim um recorde.
2009 12 06 02
corre por uma semana
2009 12 13 01
corre por quatro semanas Repete 4 vezes a data de incremento em 7
2009 12 20 01
corre por quatro semanas
2009 12 27 01
corre por quatro semanas
2009 01 03 01
corre por quatro semanas
2009 12 20 02
corre por quatro semanas Repete 4 vezes a data de incremento em 7
2009 12 27 02
corre por quatro semanas
2009 01 03 02
corre por quatro semanas
2009 01 10 02
corre por quatro semanas
Meus pensamentos devem ter algum tipo de código SQL Cross Apply?
Solução
Eu tenho uma resposta barata para você. Você usa um "pré-renderizado" Weeks
tabela para criar um loop baseado em consulta. Você precisaria colocar semanas suficientes para cobrir sua gama esperada de cenários.
[Week]
1
2
3
4
Então você se junta à sua consulta em [Weeks Running]
para esta tabela, usando a desigualdade OriginalTable.WeeksRunning <= Weeks.Week
. Você acaba com uma linha por semana.
Você deduz a data adicionando Weeks.Week * 7
dias até a data incorporada no seu número de evento.
Outras dicas
Isso é algo que provavelmente seria mais simples de fazer no lado do aplicativo e não no banco de dados, mas vou dar uma chance ... isso requer um banco de dados que suporta CTEs, que eu não tenho à mão, então Isso não é testado.
WITH RECURSIVE expandedTable(eventNumber, classification, index, count, someData)
AS (
SELECT eventNumber, classification, 1, weeksRunning, someData
FROM originalTable
WHERE weeksRunning > 0
UNION ALL
SELECT eventNumber + 7, classification, index + 1, count, someData
FROM expandedTable
WHERE index < count
)
SELECT eventNumber, classification, someData
FROM expandedTable;