2015-06-02 51 views
1

我有一個表存儲不同日期的A和B的值。它看起來像這樣:匹配表中不同變量的最後一個值

Date Amount Type 
2015 15  A 
2014 -3  B 
2013  8  B 
2013 10  A 
2012  5  A 

如何最有效準備,對於每個日期列出當前A和電流B值的表?這個想法是,對於每個日期,其中一個值是直接指定的,但另一個值需要是最後一個。

Date A B 
2015 15 -3 
2014 10 -3 
2013 10 8 

的數據集將是可觀。(數百萬條記錄),我會感謝你的幫助。該解決方案將在SAS中實施,因此我將使用SAS過程或proc sql過程(它在自連接時有其侷限性)。

+1

我想用'retain'數據步驟是你最好的選擇。 SAS proc sql缺少一些關鍵功能,沒有這些功能,語法真的很模糊。 –

+1

你現在怎麼接近它?你說'最有效' - 那麼我們將這個比作什麼?什麼是重要的 - 速度,簡單性,可重用性?至少,請提供您的代碼,以瞭解您現在如何嘗試執行此操作。 – Joe

+0

@GordonLinoff:謝謝,DomPazz提出的保留數據步驟沒有問題。出於好奇,proc sql中缺少的功能會使SQL更容易嗎? –

回答

1

戈登在評論中說,我會用一個數據步驟和RETAIN聲明

首先,創建自己的數據集。

其次,排序它通過DATE

三升序排列,使用Data Step和RETAIN創造自己的價值。使用BY語句和子集IF輸出給定DATE的所有值。

最後,在DATE中按降序排序,爲您提供所需的訂單。

data have; 
input Date Amount Type $; 
datalines; 
2015 15  A 
2014 -3  B 
2013  8  B 
2013 10  A 
2012  5  A 
; 
run; 

proc sort data=have; 
by date; 
run; 

data want(keep=date a b); 
set have; 
by date; 
retain a b; 

if Type = "A" then 
    a = amount; 
else if Type = "B" then 
    b = amount; 

if last.date; 
run; 

proc sort data=want; 
by descending date; 
run; 

這將產生:

enter image description here

0

基本上,你想加入到你的桌子爲每個案件。

我不清楚你的邏輯決定是使用當前還是先前的A金額或B金額,但是你應該能夠填寫以下語句。

select distinct <br> 
    dates.[date]<br> 
    , CASE WHEN {condition for A} THEN currentA.amount ELSE prevA.amount END as A<br> 
    , CASE WHEN {condition for B} THEN currentB.amount ELSE prevB.amount END as B<br> 
from myTable dates<br> 
LEFT OUTER JOIN myTable currentA on dates.[date] = currentA.[date] and currentA.[type] = 'A'<br> 
LEFT OUTER JOIN myTable currentB on dates.[date] = currentB.[date] and currentB.[type] = 'B'<br> 
LEFT OUTER JOIN myTable prevA on dates.[date]-1 = prevA.[date] and prevA.[type] = 'A'<br> 
LEFT OUTER JOIN myTable prevB on dates.[date]-1 = prevB.[date] and prevB.[type] = 'B'<br> 
order by dates.[date] desc<br> 

爲了表現略好,你可以組日期到一個臨時表,並使用爲出發表,而不是使用不同的關鍵字。我沒有這樣做,以保持查詢的簡短。

+0

你假設沒有兩年有差距。 –

0
data have; 
input Date Amount Type $; 
cards; 
2015 15  A 
2014 -3  B 
2013  8  B 
2013 10  A 
2012  5  A 
; 
data want(keep=date A B); 
    merge have have(firstobs=2 rename=(date=_date amount=_amount type=_type)); 
    retain flag; 
    if date-_date=1 then do; 
     if flag=1 then do; 
      call missing(flag); 
      return; 
     end; 
     if type='A' then do; 
     A=amount; 
     B=_amount; 
     end; 
     else if type='B' then do; 
     B=amount; 
     A=_amount; 
     end; 
     output; 
    end; 
    else if date=_date then do; 
     flag=1; 
     if type='A' then do; 
     A=amount; 
     B=_amount; 
     end; 
     else if type='B' then do; 
     B=amount; 
     A=_amount; 
     end; 
     output; 
    end; 
    else if missing(_date) then do; 
     if flag=1 then return; 
     if type='A' then A=amount; 
     else B=amount; 
     output; 
    end; 
run; 
相關問題