Eu tenho uma tabela com dados e datas assim:
DECLARE @p TABLE (P_key int, P_Data char(1), P_ValidUntil datetime)
INSERT @p VALUES (20, 'T', '2003-02-28')
INSERT @p VALUES (21, 'U', '2005-05-31')
INSERT @p VALUES (30, 'V', '2006-09-30')
INSERT @p VALUES (30, 'W', '2008-04-30')
INSERT @p VALUES (31, 'X', '2007-06-30')
INSERT @p VALUES (32, 'Y', '2005-01-31')
INSERT @p VALUES (32, 'Z', '2007-06-30')
INSERT @p VALUES (33, 'A', '2005-06-30')
Dado: qKey (somente múltiplos de 10), qDate
Find: Todas as entradas que correspondem a qKey no primeiro dígito e têm uma data maior que qDate. Retorna apenas um resultado por P_key (aquele com o próximo P_ValidUntil a qDate mais alto).
A solução atual é:
DECLARE @qKey AS int;
DECLARE @qDate AS datetime;
SET @qKey=30;
SET @qDate='2006-01-01';
SELECT * FROM @p WHERE
@qKey = (P_Key/10)*10
AND @qDate <= P_ValidUntil
que retorna:
30 V 2006-09-30 00:00:00.000
30 W 2008-04-30 00:00:00.000
31 X 2007-06-30 00:00:00.000
32 Z 2007-06-30 00:00:00.000
Isso está basicamente correto, exceto que há duas entradas para 30 (ambas são maiores que @qDate). Eu quero apenas a menor data desses vários hits no resultado:
30 V 2006-09-30 00:00:00.000
31 X 2007-06-30 00:00:00.000
32 Z 2007-06-30 00:00:00.000
Desde já, obrigado!
Uma primeira correção seria:
obrigado.
Use uma função de janela
FYI: ambas as técnicas usadas nas 2 respostas são bastante comuns porque é um problema comum. Exemplos aqui nessa questão do DBA-SE: Como pegar a linha MAX