Использование 8i делает это немного более сложным, чем это могло бы быть в более поздних версиях.
Вы можете создать список всех месяцев в пределах охватываемых существующих данных с иерархическим запросом, начиная с самой ранней датой и количества месяцев:
select item, min(period_start_date) min_date,
months_between(max(period_start_date), min(period_start_date)) as num_months
from your_table
group by item
... и использовать это в качестве внутренний запрос для иерархического запроса:
select item, add_months(min_date, level) as period_start_date
from (
select item, min(period_start_date) min_date,
months_between(max(period_start_date), min(period_start_date)) as num_months
from your_table
group by item
)
connect by level < num_months
Это дает вам, в этом случае, шесть фиктивных строки, за апрель по августу. (Мы знаем, что нам не нужны фиктивные строки в марте или сентябре).
Тогда вы можете исключить из списка настоящие данные с not exists
; и союз, с данными реальной таблицы:
select item, period_start_date, qty_used
from your_table
union all
select item, period_start_date, 0
from (
select item, add_months(min_date, level) as period_start_date
from (
select item, min(period_start_date) min_date,
months_between(max(period_start_date), min(period_start_date)) as num_months
from your_table
group by item
)
connect by level < num_months
) t
where not exists (
select null
from your_table
where item = t.item
and period_start_date = t.period_start_date
)
order by item, period_start_date;
ITEM PERIOD_STAR QTY_USED
---------- ----------- ----------
1234 01-MAR-2015 10
1234 01-APR-2015 0
1234 01-MAY-2015 0
1234 01-JUN-2015 32
1234 01-JUL-2015 14
1234 01-AUG-2015 0
1234 01-SEP-2015 11
С фиксированной датой начала вы можете изменить сгенерированную таблицу:
select item, period_start_date, qty_used
from your_table
union all
select item, period_start_date, 0
from (
select item, add_months(date '2013-03-01', level - 1) as period_start_date
from (select distinct item from your_table)
connect by add_months(date '2013-03-01', level - 1) < sysdate
) t
where not exists (
select null
from your_table
where item = t.item
and period_start_date = t.period_start_date
)
order by item, period_start_date;
Вы можете также левую внешнее соединение из сгенерированных данных таблицы, но конечно, придется использовать старый синтаксис, специфичный для Oracle:
select t.item, t.period_start_date, nvl(yt.qty_used, 0) as qty
from (
select item, add_months(date '2013-03-01', level - 1) as period_start_date
from (select distinct item from your_table)
connect by add_months(date '2013-03-01', level - 1) < sysdate
) t, your_table yt
where yt.item (+) = t.item
and yt.period_start_date (+) = t.period_start_date
order by t.item, t.period_start_date;
Ну, это форматирование не получилось. Я использовал много пробелов для имитации столбцов, но, очевидно, это не сработало. Ясно, что я новичок: - | –
[Как отформатировать мои сообщения с помощью Markdown или HTML?] (Http://stackoverflow.com/help/formatting). Стоит посмотреть вокруг справочного центра или, по крайней мере, [принять тур] (http://stackoverflow.com/tour), если вы еще этого не сделали. –
Как определить начальный и конечный месяцы - самый низкий и самый высокий в таблице, или вы можете увидеть данные за март 2015 года, даже если в этом месяце нет строки, скажем? –