No exemplo abaixo, preciso buscar a linha que possui os dados mais recentes com base em uma combinação de datas. Não posso simplesmente fazer MAX(insert_date), MAX(update_date)
, pois não retorna os dados corretos. A maneira como funciona agora é obter o MAX(insert_date)
then do self join para obter o MAX(update_date)
then self join para retornar os valores da linha.
Existe uma maneira melhor e mais eficiente de fazer isso? O exemplo abaixo contém apenas 4 linhas, mas em produção estarei processando cerca de 1 milhão de linhas a cada poucos minutos.
Exemplo:
create table #temp (
iud char(1) not null,
id int not null,
date date not null,
value decimal(9,2) not null,
insert_date datetimeoffset not null,
update_date datetime2 not null
);
insert #temp
values
('i', 1001, '2001-01-01', 2, '2001-01-01 00:00', '2001-01-01 00:00'),
('i', 1001, '2001-01-01', 9, '2001-01-01 00:00', '2001-01-01 01:00'),
('i', 1001, '2001-01-01', 7, '2001-01-02 00:00', '2001-01-01 00:30'),
('i', 1001, '2001-01-01', 4, '2001-01-02 00:00', '2001-01-01 00:00');
-- this is wrong as it returns no results
select t.*
from #temp as t
join (select iud, id, date, max(insert_date) as insert_date, max(update_date) as update_date
from #temp
group by iud, id, date) as x
on t.iud = x.iud
and t.id = x.id
and t.date = x.date
and t.insert_date = x.insert_date
and t.update_date = x.update_date;
-- this works, but can it be simplified?
select n.*
from #temp as n
join (
select n.iud, n.id, n.date, n.insert_date, max(update_date) as update_date
from #temp as n
join (select iud, id, date, max(insert_date) as insert_date
from #temp
group by iud, id, date) as i
on i.iud = n.iud
and i.id = n.id
and i.insert_date = n.insert_date
group by n.iud, n.id, n.date, n.insert_date) as x
on x.date = n.date
and x.insert_date = n.insert_date
and x.iud = n.iud
and x.id = n.id
and x.update_date = n.update_date
order by n.iud, n.id, n.date;
drop table #temp;
Se eu entendi o que você está tentando fazer corretamente, então
Pode ter um desempenho melhor - especialmente se houver um índice de cobertura em
(iud, id, date, insert_date DESC, update_date DESC)