2015-03-23 2 views
1

Я хотел бы получить за N макс (дата) < = sysdate. Если нет дат в прошлом/сегодня, я хочу мин (дата). Поэтому мне не нужна абсолютная дата, ближайшая к sysdate.Получить ближайшую к sysdate дату

Testdata

CREATE TABLE DATTEST (N NUMBER, D DATE); 

INSERT INTO DATTEST (N,D) VALUES (1,TRUNC(SYSDATE-2000)); 
INSERT INTO DATTEST (N,D) VALUES (1,TRUNC(SYSDATE-1000)); 
INSERT INTO DATTEST (N,D) VALUES (1,TRUNC(SYSDATE+100)); 

INSERT INTO DATTEST (N,D)VALUES (2,TRUNC(SYSDATE)); 
INSERT INTO DATTEST (N,D)VALUES (2,TRUNC(SYSDATE+1000)); 


INSERT INTO DATTEST (N,D)VALUES (3,TRUNC(SYSDATE+1000)); 

До сих пор я получил это. Он дает правильную шину результатов, делает две таблицы. Я работаю над большими таблицами, и этот запрос вызывается много раз. Я ломаю голову, превращая это в одно сканирование таблицы.

with nums as 
    (SELECT LEVEL num 
    FROM DUAL 
    CONNECT BY LEVEL <= 3 
    ) 
select 
num 
,(nvl((select max(d) 
    from dattest 
    where d <= trunc(sysdate) 
    and n = num), 
    (select min(d) 
    from dattest 
    where d > trunc(sysdate) 
    and n = num)) 
) 
from nums; 

Ожидаемый результат

1 26-06-12 
2 23-03-15 
3 17-12-17 

ответ

2

Как об использовании агрегации, с некоторой условной логики?

select id, 
     coalesce(max(case when d <= trunc(sysdate) then d end), 
       min(d) 
       ) 
from table t 
group by id; 
+1

Вы должны использовать "<=": выбора п, коалесценции (макс (случай, когда d <= SYSDATE то й конец), мин (г) ) из dattest группы по п; –

Смежные вопросы