Похоже, вам нужно сгенерировать дату (ы), а затем посмотреть, как записи могут соответствовать каждой. Предполагая, что у вас нет данных в будущем, вы можете сделать что-то вроде:
select trunc(sysdate) + level - (:range + 1) as dt
from dual
connect by level <= (:range + 1);
который с: диапазон установлен в 1 дает две даты:
DT
---------
19-JUL-11
20-JUL-11
Затем вы можете получить внешнее присоединение к этому списку дат:
with tmp_dt as (
select trunc(sysdate) + level - (:range + 1) as dt
from dual
connect by level <= (:range + 1)
)
select td.dt as mydt,
case when count(t.year) = 0 then 1 else 0 end as result
from tmp_dt td
left join table1 t on t.year = extract(year from td.dt)
and t.month = extract(month from td.dt)
and t.day = extract(day from td.dt)
group by td.dt
order by td.dt;
Если у меня есть какие-либо данные в таблице только 19 июля-11, я получу:
MYDT RESULT
--------- ----------
19-JUL-11 0
20-JUL-11 1
Если у вас есть данные в будущем, они не будут показаны; range
- это сколько дней смотреть в прошлое. Если вы знаете, что есть предел, скажем, семь дней, вы можете использовать connect by level <= (:range + 1) + 7
или иметь вторую переменную, но это скорее зависит от того, что вы хотите увидеть.
Я немного поменял объединение, чтобы избежать преобразования даты для каждой строки таблицы, вместо этого извлекая соответствующую часть сгенерированной даты. Я надеюсь, что у вас есть причина хранить компоненты даты в отдельных полях, а не как date
.
Если вы ищете только данные за сегодня, просто измените генератор даты:
with tmp_dt as (select trunc(sysdate) as dt from dual)
select td.dt as mydt,
case when count(t.year) = 0 then 1 else 0 end result
from tmp_dt td
left join table1 t on t.year = extract(year from td.dt)
and t.month = extract(month from td.dt)
and t.day = extract(day from td.dt)
group by td.dt;
Если вы всегда хотите вчера, это будет select trunc(sysdate) - 1 as dt from dual
и т. Д.