Количество дней в месяце против непрерывной даты

Я получил SQL-запрос, в котором указана дата (D1), когда товар был в магазине, и дата (D2), когда товар вышел. Я хочу подсчитать, сколько дней товар оставался в магазинах. D2-D1 - это легкий расчет. Моя проблема теперь, если продукт вошел в 28/28 и вышел 12/03.

Я хочу показать, что он остался 3 дня в ноябре и 3 дня в декабре. Как я могу продолжить это? Ищем количество дней только за месяц.

Заранее спасибо,

2 ответа

Решение

Ключ должен использовать первый день месяца для D2: trunc(D2,'mm')

select case when D1 < trunc(D2,'mm') then trunc(D2,'mm') - D1  
       else 0 end as days_previous_months,
        case when D1 < trunc(D2,'mm') then D2 - trunc(D2,'mm') + 1 
        else D2 -D1 + 1 end as in_month
from table1

Даже первое, что вы сказали, неверно: если вы хотите, чтобы в число дней входили как первая, так и последняя дата, как вам кажется, тогда формула будет 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
Другие вопросы по тегам