基于 "from" 和 "to" 日期的重复行

Duplicate rows based on "from" and "to" dates

我有一个 table 类似的(SAS SQL 中的代码,但我可以转换来自 SQL 服务器引擎的回复,因为我在这方面有一些经验):

proc sql;
   create table work.temp1
       (date_from num informat=date7. format=date7.,
        date_to num informat=date7.   format=date7.,
        some_number num);

insert into work.temp1
    values('15MAY2018'd,'26JUL18'd, 10);
QUIT;

结果:

我想将其转换为(通过一些巧妙的连接和可能带有日期和月份的临时 table)到:

proc sql;
   create table work.temp2
       (date_from num informat=date7. format=date7.,
        date_to num informat=date7.   format=date7.,
        some_number num);

insert into work.temp2
    values('15MAY2018'd,'31MAY18'd, 10)
    values('1JUN2018'd,'30JUN18'd, 10)
    values('1JUL2018'd,'26JUL18'd, 10);
QUIT;

结果:

应复制所有其他列。开始日期和结束日期始终在一个日历日期中,但每一行可以在不同的年份 (2016-2020)。

[编辑]:

Tom 解决方案看起来不错,但在我使用之前,我正在尝试开发 SQL 解决方案。

我在我的数据库中添加了一个 "calendar" table,它看起来像: 姓名:work.calendar

现在我正在考虑的连接类似于:

SELECT t1.* 
FROM work.temp1 t1 INNER JOIN 
     work.calendar t2 ON t1.date_from >= t2.month_FROM AND t1.date_to <= month_TO

但是显然不行

基本上你想把你的经期转换成月度记录。使用 SAS 代码很容易做到,但使用 SQL 会更难,因为它是基于集合而不是顺序处理。

那么让我们从创建测试数据开始吧。

data temp1;
  date_from='15MAY2018'd;
  date_to='26JUL18'd;
  some_number= 10;
  format date_: date9. ;
run;

intck()函数可用于确定区间数。 intnx() 函数可以用来查找月份的 beginning/ending。您还可以添加代码行来重命名新变量并删除旧变量和循环计数器。

data want ;
  set temp1 ;
  do i=0 to intck('month',date_from,date_to);
    from = max(intnx('month',date_from,i,'b'),date_from);
    to = min(intnx('month',date_from,i,'e'),date_to);
    output;
  end;
  format from to date9.;
  rename from=date_from to=date_to;
  drop date_from date_to i ;
run;