根据“开始”和“结束”日期重复行

时间:2018-09-12 11:48:35

标签: sql sql-server sas proc-sql

我有一个类似的表(SAS SQL中的代码,但我有经验,因此可以转换来自SQLServer引擎的回复):

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;

结果:

enter image description here

并且我想将其转换为(具有一些巧妙的连接,并可能有一些带有日期和月份的临时表)为:

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;

结果:

enter image description here

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

[编辑]:

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

我在数据库中添加了一个“ calendar”表,它看起来像: 名称:work.calendar enter image description here

现在我正在考虑的联接将是这样的:

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

但这显然不起作用。

1 个答案:

答案 0 :(得分:2)

基本上,您希望将期间转换为月度记录。使用SAS代码非常容易,但是使用SQL则要困难得多,因为它是基于设置而不是顺序处理的。

因此,让我们从创建测试数据开始。

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

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

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;

enter image description here