Eu tenho uma tabela que possui uma identificação, um valor e uma data. Existem muitos IDs, valores e datas nesta tabela.
Os registros são inseridos nessa tabela periodicamente. O ID sempre permanecerá o mesmo, mas ocasionalmente o valor será alterado.
Como posso escrever uma consulta que me forneça o ID mais a hora mais recente em que o valor foi alterado? Nota: o valor sempre aumentará.
A partir desses dados de amostra:
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.)
sql-server
sql-server-2008-r2
t-sql
SqlSandwiches
fonte
fonte
taco
que não tenha nada a ver com a comida?Respostas:
Essas duas consultas se baseiam 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 quem acompanha, houve uma disputa sobre o que acontece se
Taco_value
alguma vez se repetir. Se for de 1 para 2 e depois voltar para 1Taco_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 umaTaco_value
.Se você deseja incluir a primeira linha de qualquer ID em que o valor não foi alterado em todo o conjunto:
Se você deseja excluir essas linhas, é um pouco mais complexo, mas ainda há pequenas alterações:
Exemplos atualizados do SQLfiddle
fonte
value
reaparece: FiddleBasicamente, esta é a sugestão de @ Taryn "condensada" para um único SELECT sem tabelas derivadas:
Nota: esta solução leva em consideração a estipulação que
Taco_value
só pode aumentar. (Mais exatamente, pressupõe queTaco_value
não possa voltar a um valor anterior - mesmo que a resposta vinculada, na verdade).Uma demonstração do SQL Fiddle para a consulta: http://sqlfiddle.com/#!3/91368/2
fonte
Você deve poder usar as funções agregadas
min()
emax()
obter o resultado:Veja SQL Fiddle com demonstração
fonte
Mais uma resposta baseada na suposição de que os valores não reaparecem (essa é basicamente a consulta 2 de Aaron 2, 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 avalue
, seja mostrada):Teste em: SQL-Fiddle-2
fonte
dbo.Taco UNION ALL SELECT DISTINCT Taco_ID, NULL AS Taco_value, '19000101' AS Taco_date
).FYI +1 por fornecer dados e estrutura da amostra. A única coisa que eu poderia ter pedido é a saída esperada para esses dados.
Edição: Este estava indo me deixar louco. Eu apenas novo, 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 ao @bluefeets, mas abrange os testes que o @AaronBertrand deu.
fonte
value
mudanças são feitas.Por que não apenas obter a diferença entre o valor do atraso e o valor do lead? se a diferença é zero, não mudou, não é zero, mudou. Isso pode ser feito em uma consulta simples:
fonte
lag...
função analítica foi introduzida "recentemente" apenas no SQL Server 2012. A pergunta original está solicitando uma solução no SQL Server 2008 R2. Sua solução não funcionaria para o SQL Server 2008 R2.Isso pode ser tão simples quanto o seguinte?
Dado que taco_value sempre aumenta?
ps Eu mesmo sou iniciante em SQL, aprendendo devagar, mas com segurança.
fonte
Cannot perform an aggregate function on an expression containing an aggregate or a subquery