2016-03-25 9 views
0

Ich muss Datensätze/Zeilen zu einer vorhandenen Tabelle, basierend auf den Werten eines Paares Felder hinzufügen. Die Reihen sind im Grunde die Strecke der Monate für jede unterschiedliche Identifikation - die meisten IDs haben mehrere Monate, aber einige nur einen Monat.Verwendung von sas oder sql Hinzufügen neuer Datensätze zu Tabelle basierend auf monatlichen Datumsvariablen

Ich habe ein first_date Feld und ein last_date Feld und muss Zeilen für die dazwischen liegenden Monate zwischen den beiden Daten ausfüllen und eine "time id" für die Zeile erstellen, die diesen Monat identifiziert.

Aktuell:

enter image description here

Antwort

0

Wenn Sie eine Zusammenfassung verwenden, können Sie FREQ total_months; in den meisten Procs oder in Proc Freq ist es GEWICHT.

Ich muss wirklich erweitern Ich denke, das wird ausreichen.

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

Beginnend mit dem einfachsten zuerst - ich denke wirklich, dass dies getan hat - Danke data_null! – user3791254

0

Was ich denke, du wirst eine zusätzliche Tabelle müssen, ist, eine Dimension oder Zuordnungstabelle, die Ihnen Informationen zu diesen Terminen/Monat geben. Ich denke, Sie können sich dann ein paar Mal daran beteiligen, um Ihre vollständige Liste zu erhalten.

Hier ist, was ich getan habe:

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 

Dies war nur eine Tabelle erstellen Sie nachahmen ...

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 

Dies war eine Tabelle mit Monat Informationen, wie der Auftrag/Rang zu schaffen .

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 

Dieser dritte Schritt zieht in Informationen über den ersten Monat (Join m), die im letzten Monat (zusammen m2) und dann alle die Monate dazwischen (m3).

Wenn Sie weiterhin den '01jan2015'-Stil von Daten verwenden, wäre es wahrscheinlich nützlich, eine Datumsdimensionstabelle zu erstellen, um eine Reihe relevanter Informationen in Spalten zu speichern .... Monat, Jahr usw.

0

Eine weitaus prägnante Antwort: https://stackoverflow.com/a/36222217/6111039


Der folgende Code soll Pflege des schwierigen Teils nehmen. Informationen zum Umgang mit time_id finden Sie unter http://www.ats.ucla.edu/stat/sas/faq/enumerate.htm.

/*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; 

Beachten Sie, dass ich hier nur die Variablen first_date und last_date als Strings eingeben, um Zeit zu sparen. Sie können die Funktion month() mit Datumsvariablen verwenden, um Informationen zu erhalten, die Sie für die Behandlung von time_id nützlich finden (z. B. month (01jul2015) = 7).