2017-06-28 10 views
1

,producteventが発生し、発生するイベントに対応するtimeがある以下の形式の表があります。SQL:最後の等しくないイベントの日付差

UID | |Product | Event | Time 
A  C1   F  2017-06-23 
A  C2   S  2017-06-21 
A  C1   S  2017-06-19 
A  C1   S  2017-06-17 
B  C3   F  2017-06-12 
B  C3   S  2017-06-12 
C  C2   F  2017-06-02 
C  C2   F  2017-06-01 

私は、各ユーザーおよび製品のF現在のイベントに、以前のSイベントからの時間差を見つけるしたいと思います。

UID | |Product | Event | Time  | Days_Diff 
A  C1   F  2017-06-23 4 
A  C2   S  2017-06-21 NULL 
A  C1   S  2017-06-19 NULL 
A  C1   S  2017-06-17 NULL 
B  C3   F  2017-06-12 0 
B  C3   S  2017-06-12 NULL 
C  C2   F  2017-06-02 NULL 
C  C2   F  2017-06-01 NULL 

は、私は以下のようなものを試してみましたが、それは

SELECT UID, Product, Event, Time, 
     CASE 
     -- product is equal to last product 
     WHEN Product = LAG(Product, 1) OVER (PARTITION BY UID, Product ORDER BY Time) 
     -- current event = F and last event = S 
     AND Event = 'F' AND LAG(Event, 1) OVER (PARTITION BY UID, Product ORDER BY Time) = 'S' 
     -- subtract current time by the last time this product was activated 
     THEN DATEDIFF('DAY', MAX(Time) OVER (PARTITION BY UID, Product ORDER BY Time 
            ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING), Time) 
     END AS days_diff 
FROM table 

しかしこれは、私は、ユーザーが起動した場合を比較する助​​けにはならない、私は最後の製品とイベントを追跡するのに役立ちていませんSイベントの直後にFイベントが続きます。例えば。次のような場合

UID | |Product | Event | Time  | Days_Diff 
A  C1   F  2017-06-23 4 
A  C2   S  2017-06-21 NULL 
A  C1   S  2017-06-19 NULL 
A  C1   S  2017-06-17 NULL 

この問題はどのように解決すればよいですか?

+0

PostgresまたはRedshiftを使用していますか? –

+0

@GordonLinoffは、タグをRedshiftのみとSQLに変更しました。 – Black

+0

上記のシナリオで述べたように、データのdays_diffはどのようにする必要がありますか? –

答えて

1

最初の「S」から「F」までの時間が必要なようです。その場合:

SELECT UID, Product, Event, Time, 
     (CASE WHEN Event = 'F' 
      THEN DATEDIFF(DAY, 
          MIN(CASE WHEN Event = 'S' THEN Time END) 
           OVER (PARTITION BY UID 
            ORDER BY TIME 
            ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING 
            ), 
          Time 
         ) 
     END) AS days_diff 
FROM table; 

注:これはRedshiftのDATEDIFF()機能を使用します。最初の引数(私が知る限り)は文字列ではなく、日付部分です。

EDIT:

私が見るには、あなたが同じ製品の "S" をします。これはちょっと違います:

SELECT UID, Product, Event, Time, 
     (CASE WHEN Event = 'F' 
      THEN DATEDIFF(DAY, 
          MAX(CASE WHEN Event = 'S' THEN Time END)          
           OVER (PARTITION BY UID 
            ORDER BY TIME 
            ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING 
            ), 
          Time 
         ) 
     END) AS days_diff 
FROM table; 
+0

私は実際にそのユーザーの最後の 'S'からの日を探しており、製品は – Black

+0

@Blackです。 。 。これはあなたのサンプルの結果が示すものではありません。 –

+0

ユーザー「A」に別の行を追加して編集しました。それは役に立ちますか? – Black