每月天数与连续日期

count of days per month vs continuous date

我得到了一个 SQL 查询,它给出了产品入库日期 (D1) 和产品售出日期 (D2)。我想计算产品在商店中停留了多少天。 D2-D1 是简单的计算。 我现在的问题是产品是否在 11 月 28 日进入并在 12 月 03 日离开。

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

提前致谢,

关键是使用 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 的单独列,因为有可能(即使它不经常发生)相同的产品(具有相同的 ID)可能 "enter" 和 "exit" 不止一次。如果同一产品在同一个月内进入和退出两次,持续六天,然后又持续四天,我假设您希望将这些显示为单独的计数,对于两个 "entry events"(而不是单个条目持续十天的事件)。

像这样。请注意,我在 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