使用 sas 或 sql 根据每月日期变量将新记录添加到 table

Using sas or sql add new records to table based on monthly date variables

我需要根据几个字段的值将 records/rows 添加到现有的 table。这些行基本上是每个不同 ID 的月份范围——大多数 ID 会有多个月,但有些只有一个月。

我有一个 first_date 字段和一个 last_date 字段,需要填写行,但是中间月份在两个日期之间,并为标识该行的行创建 "time id"月。

当前:

我认为您需要的是一个额外的 table,一个维度或映射 table,它将为您提供有关这些 dates/months 的信息。认为您可以加入几次以获得完整列表。

这是我所做的:

    CREATE TABLE #tblCurrent 
  (ID INT,
  First_Date VARCHAR(9),
  Last_Date VARCHAR(9),
  TotalMonths INT,
  VAR1 INT,
  VAR2 INT)

  INSERT INTO #tblCurrent
  SELECT 123,'01jan2015','01mar2015',3,5,2
  union 
  SELECT 124,'01jul2015','01aug2015',2,5,2
  union 
  SELECT 125,'01jan2015','01jan2015',1,5,2

这只是为了创建一个 table 模仿你的...

CREATE TABLE #Month
  ([MonthName] VARCHAR(9),
  MonthRank INT)

  INSERT INTO #Month
  SELECT '01jan2015', 1
    union SELECT '01feb2015', 2
    union SELECT '01mar2015', 3
    union SELECT '01apr2015', 4
    union SELECT '01may2015', 5
    union SELECT '01jun2015', 6
    union SELECT '01jul2015', 7
    union SELECT '01aug2015', 8
    union SELECT '01sep2015', 9
    union SELECT '01oct2015', 10
    union SELECT '01nov2015', 11
    union SELECT '01dec2015', 12

这是为了创建一个带有月份信息的 table,例如 order/rank。

  SELECT c.*, m3.MonthRank Time_ID
  FROM #tblCurrent c
  JOIN #Month m ON c.First_Date = m.[MonthName]
  JOIN #Month m2 ON c.Last_Date = m2.[MonthName]
  JOIN #Month m3 ON m3.MonthRank >= m.MonthRank and m3.MonthRank <=m2.MonthRank
  ORDER BY ID, m3.MonthRank

第三步提取第一个月(join m)、最后一个月(join m2)以及其间所有月份(m3)的信息。

如果您打算继续使用日期的“01jan2015”样式,构建日期维度 table 以在列中存储一堆相关信息可能会很有用....月, 年份等..

如果您使用的是摘要,您可以使用 FREQ total_months;在大多数 procs 或 proc freq 中,它是 WEIGHT。

我真的需要扩展,我想这就足够了。

data expand;
   set <data-name>;
   do time_id = 1 to total_months;
      output;
      end;
   run;

更简洁的回复:


下面的代码应该处理困难的部分。请参阅 http://www.ats.ucla.edu/stat/sas/faq/enumerate.htm 了解如何处理 time_id。

/*your dataset*/
data tempy;
   input id fd $ ld $ total_months time_id;
   datalines;
        123 jan mar 3 .
        124 jul aug 2 .
        125 jan jan 1 .
    ;
run;

/*make a copy of it*/
data tempy2;
    set tempy;
run;

/*select the total_months and id variables into lists*/
proc sql noprint;
    select total_months into: months_list
    separated by " "
    from tempy;
quit;

%put &months_list.;

proc sql noprint;
    select id into: ids_list
    separated by " "
    from tempy;
quit;

%put &ids_list.;


%macro inserter;

    /*for every row in the original dataset, keep track of id and how many total_months it has*/
    %do i = 1 %to %sysfunc(countw(&months_list.));
    %let this_id = %scan(&ids_list., &i.);
    %let this_many_months = %scan(&months_list., &i.);

        /*insert the same observation into the original dataset (total_months - 1) times for each row*/
        %do j = 1 %to (&this_many_months. - 1);

            proc sql;
                insert into tempy select distinct * from tempy2 (where = (id = &this_id.));
            quit;

        %end;
    %end;

    /*sort*/
    proc sort data = tempy;
        by id;
    run;

%mend inserter;

%inserter;

请注意,为了节省时间,我只是将 first_date 和 last_date 变量输入为字符串。您可以使用带有日期变量的 month() 函数来获取对处理 time_id 有用的信息(例如,month(01jul2015) = 7)。