每月天数与连续日期的比较

时间:2018-12-03 15:39:57

标签: oracle date date-range continuous sysdate

我得到了一个SQL查询,该查询给出了产品进入商店的日期(D1)和产品停产的日期(D2)。我想计算产品在商店中停留了几天。 D2-D1是简单计算。 现在我的问题是,如果该产品于11/28进入并于12/03退出。

我想证明它在11月停留了3天,在12月停留了3天。 我该如何进行?寻找仅一个月的天数。

谢谢,

2 个答案:

答案 0 :(得分:3)

即使您说的第一句话是不正确的:如果您希望日数包括看上去的第一个和最后一个日期,那么公式为D2-D1 + 1,而不是D2-D1。

除此之外,这是执行此操作的一种方法。我假设您有一个用于product_id的列,但还有一个用于entry_id的单独列,因为相同的产品(具有相同的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

答案 1 :(得分:0)

关键是要使用D2的第一天:preg_replace('/^(,|\s)+|(,|\s)+$/', '', 'sacas')

trunc(D2,'mm')