Eu tenho uma tabela que tem um ID, um valor e uma data. Há muitos IDs, Valores e datas nesta tabela.
Os registros são inseridos nesta tabela periodicamente. O ID permanecerá sempre o mesmo, mas ocasionalmente o valor mudará.
Como posso escrever uma consulta que me dará o ID mais a hora mais recente em que o valor foi alterado? Nota: o valor sempre aumentará.
A partir destes dados de exemplo:
Create Table Taco
( Taco_ID int,
Taco_value int,
Taco_date datetime)
Insert INTO Taco
Values (1, 1, '2012-07-01 00:00:01'),
(1, 1, '2012-07-01 00:00:02'),
(1, 1, '2012-07-01 00:00:03'),
(1, 1, '2012-07-01 00:00:04'),
(1, 2, '2012-07-01 00:00:05'),
(1, 2, '2012-07-01 00:00:06'),
(1, 2, '2012-07-01 00:00:07'),
(1, 2, '2012-07-01 00:00:08')
O resultado deve ser:
Taco_ID Taco_date
1 2012-07-01 00:00:05
(Porque 00:05 foi a última vez que Taco_Value
mudou.)
Essas duas consultas baseiam-se na suposição de que
Taco_value
sempre aumenta com o tempo.Uma alternativa com menos loucura de função de janela:
Exemplos no SQLfiddle
Atualizar
Para aqueles que acompanham, houve disputa sobre o que aconteceria se
Taco_value
pudesse se repetir. Se puder ir de 1 a 2 e depois voltar a 1 para qualquer dadoTaco_ID
, as consultas não funcionarão. Aqui está uma solução para esse caso, mesmo que não seja exatamente a técnica de lacunas e ilhas que alguém como Itzik Ben-Gan possa sonhar, e mesmo que não seja relevante para o cenário do OP - pode ser relevante para um futuro leitor. É um pouco mais complexo e também adicionei uma variável adicional - umaTaco_ID
que só tem umTaco_value
.Se você quiser incluir a primeira linha para qualquer ID em que o valor não mudou em todo o conjunto:
Se você deseja excluir essas linhas, é um pouco mais complexo, mas ainda com pequenas alterações:
Exemplos de SQLfiddle atualizados
Basicamente, esta é a sugestão de @Taryn "condensada" em um único SELECT sem tabelas derivadas:
Nota: esta solução tem em conta a estipulação que
Taco_value
só pode aumentar. (Mais exatamente, ele assume queTaco_value
não pode voltar para um valor anterior - o mesmo que a resposta vinculada, na verdade.)Uma demonstração do SQL Fiddle para a consulta: http://sqlfiddle.com/#!3/91368/2
Você deve ser capaz de usar as duas funções
min()
emax()
agregar o resultado:Veja SQL Fiddle com demonstração
Mais uma resposta baseada na suposição de que os valores não reaparecem (isso é basicamente a consulta 2 do @Aaron, condensada em um ninho a menos):
Teste em: SQL-Fiddle
E uma resposta para o problema mais geral, onde os valores podem reaparecer:
(ou usando
CROSS APPLY
para que toda a linha relacionada, incluindo ovalue
, seja mostrada):Teste em: SQL-Fiddle-2
FYI +1 para fornecer estrutura e dados de amostra. A única coisa que eu poderia ter pedido é a saída esperada para esses dados.
EDIT: Este ia me deixar louco. Acabei de saber que havia uma maneira "simples" de fazer isso. Eu me livrei das soluções incorretas e coloquei uma que acredito estar correta. Aqui está uma solução semelhante a @bluefeets, mas abrange os testes que @AaronBertrand deu.
Por que não apenas obter a diferença do valor do atraso e do valor do lead? se a diferença for zero, não mudou, é diferente de zero, então mudou. Isso pode ser feito em uma consulta simples:
Tive um problema semelhante hoje - e no Power BI eu poderia ter resolvido com o uso de Tabler.FillDown. Um pouco de pesquisa me levou a uma variante SQL de FillDown:
https://www.oraylis.de/blog/fill-down-table-in-t-sql-last-non-empty-value
Então, dediquei um tempo para adaptar essa solução a este exemplo - com uma linha extra adicionada para mostrar a reutilização de Taco_value.
Nota: esta solução leva em consideração que Taco_value pode aumentar E diminuir (ou voltar ao valor anterior)
Resultado:
Isso poderia ser tão simples quanto o seguinte?
Dado que taco_value sempre aumenta?
ps Eu sou bastante iniciante em SQL, no entanto, aprendendo devagar, mas com segurança.