Даже первое, что вы сказали, неверно: если вы хотите, чтобы в число дней входили как первая, так и последняя дата, как вам кажется, тогда формула будет D2 - D1 + 1, а не D2 - D1.
Кроме этого, вот один из способов сделать это.Я предполагаю, что у вас есть столбец для product_id, но также отдельный столбец для entry_id, поскольку вполне возможно (даже если это случается не часто), что один и тот же продукт (с тем же идентификатором) может «входить» и «выходить» больше, чемодин раз.Если один и тот же продукт входит и выходит два раза в одном и том же месяце, в течение шести дней, а затем снова в течение еще четырех дней, я предполагаю, что вы хотите, чтобы показанные как отдельные значения подсчитывались для двух «событий входа» (в отличие от одного события входапродолжительностью десять дней).
Как то так.Обратите внимание, что я создал несколько примеров данных в предложении WITH, которое предназначено только для тестирования, но не является частью SQL-запроса (решение, которое я предлагаю).
with
inputs (entry_id, product_id, date_in, date_out) as (
select 1331, 101, date '2018-11-28', date '2018-12-03' from dual union all
select 1332, 102, date '2018-03-09', date '2018-03-13' from dual union all
select 1333, 102, date '2017-12-31', date '2018-03-01' from dual
)
select entry_id, product_id,
to_char(start_date, 'MON yyyy') as month,
least(end_date, date_out) - greatest(start_date, date_in) + 1 as day_count
from (
select entry_id, product_id, date_in, date_out,
add_months(trunc(date_in, 'mm'), level - 1) as start_date,
add_months(trunc(date_in, 'mm'), level) - 1 as end_date
from inputs
connect by level <= 1 + months_between(trunc(date_out, 'mm'),
trunc(date_in, 'mm'))
and prior entry_id = entry_id
and prior sys_guid() is not null
)
order by product_id, start_date
;
ENTRY_ID PRODUCT_ID MONTH DAY_COUNT
---------- ---------- ----------------- ----------
1331 101 NOV 2018 3
1331 101 DEC 2018 3
1333 102 DEC 2017 1
1333 102 JAN 2018 31
1333 102 FEB 2018 28
1333 102 MAR 2018 1
1332 102 MAR 2018 5