使用 Proc SQL 中的日期范围计算条目在特定月份内处于活动状态的天数

问题描述

我在一段时间内获得了一些数据,但在弄清楚一些细节方面遇到了困难。

例如,我有大量具有活动 STARTSTOP 日期的数据行。如果发生以下三种情况之一,我已执行笛卡尔积以将我的特定数据行连接到该特定月份:

  1. 项目活动开始日期在该特定月份的第一天之前,该项目的活动停止日期在该月的第一天之后。 (ITEM_START<= CalendarMonthStart and ITEM_STOP>= CalendarMonthStart)
  2. 项目活动开始日期发生在该特定月份的第一天之后,该项目的活动停止日期发生在该特定月份的最后一天之前(活动在一个月内)。(ITEM_START>= CalendarMonthStart and ITEM_STOP>= CalendarMonthEnd)
  3. 项目活动开始日期发生在该特定月份的最后一天之前,并在该特定月份的最后一天之后停止。(ITEM_START<= CalendarMonthEnd and ITEM_STOP>= CalendarMonthEnd)

我的 proc sql 查询示例:

proc sql;
create table  earned_activity as

select
      a.ITEM_START,a.ITEM_STOP,b.MonthName,b.CalendarMonthStart,b.CalendarMonthEnd
/* Need to do something here */
from item_activity as a
left join calendar_table as b on 
          (ITEM_START<= CalendarMonthStart and ITEM_STOP>= CalendarMonthStart) or
          (ITEM_START>= CalendarMonthStart and ITEM_STOP>= CalendarMonthEnd) or
          (ITEM_START<= CalendarMonthEnd and ITEM_STOP>= CalendarMonthEnd)

;
quit;

在将这三个案例加入我的数据后,我有一些示例数据,如下所示:

ITEM_START ITEM_STOP 月份名称 CalendarMonthStart CalendarMonthEnd num_days_active
2021-01-06 2021-03-06 一月 2021-01-01 2021-01-31 25
2021-01-06 2021-03-06 二月 2021-02-01 2021-02-28 28
2021-01-06 2021-03-06 三月 2021-03-01 2021-03-31 6

如您所见,使用笛卡尔积,我有一个项目在三个不同的日历月内都有活动。我想找到一种方法获取该项目在每个月中存在的天数。我的第一个想法是在每个月的每一天执行笛卡尔乘积,如果那一天活跃,则以某种方式进行统计,但我相信这可能会很快变得庞大而繁琐。是否有执行此类操作的好方法

谢谢。

解决方法

我认为你只需要开始和结束的最大值。

SELECT
    DATEDIFF(day,CASE WHEN CalendarMonthStart > a.ITEM_START THEN CalendarMonthStart ELSE a.ITEM_START END,CASE WHEN CalendarMonthEnd   < a.ITEM_STOP  THEN CalendarMonthEnd   ELSE a.ITEM_START END)

此外,您的 WHERE 可以更简单:

inner join calendar_table as b on 
          (ITEM_START <= CalendarMonthEnd and ITEM_STOP => CalendarMonthStart)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...