2017-07-07 2 views
1

Betrachten sie mir folgende Tabelle habe:Die Suche nach Finanz-Muster der Reihen - SQL mit Rekursion

id date  transaction_type  amount 
1 2017-01-01 deposit    30 
1 2017-01-01 deposit    20 
1 2017-01-02 withdrawal   -20 
1 2017-01-02 deposit    40 
1 2017-01-04 deposit    50 
1 2017-01-05 withdrawal   -100 
1 2017-01-07 withdrawal   -10 
1 2017-01-09 deposit    100 
1 2017-01-11 withdrawal   -50 
1 2017-01-21 deposit    20 
1 2017-01-22 deposit    30 
1 2017-01-31 withdrawal   -60 
2 2017-01-01 deposit    200 
... ...   ...     ... 

Die Daten in der Tabelle werden von den ältesten zum neuesten für jede ID bestellt (Zeitstempel nicht sichtbar ist). Ich würde gerne finden, wie oft eine bestimmte Transaktion Muster stattgefunden hat:

Anzahlung -> Anzahlung -> Rückzug, und die Zeit zwischen der ersten Einzahlung und dem Abzug beträgt 7 Tage oder weniger.

Also für den Kunden mit ID = 1 hätte ich 2 solche Fälle (der dritte erfüllt nicht die Zeitbedingung).

Als Ergebnis würde Ich mag die folgende Tabelle erhalten:

id number_of_times 
1 2 
2 ... 
... ... 

Ist es etwas, das in SQL getan werden kann? Würde ich eine Rekursion benötigen, um zum Finaltisch zu kommen?

UPDATE: Wie richtig hingewiesen, gibt es keine dazwischenliegenden Transaktionen - aber was ist, wenn es einige waren? Wie jede Anzahl von anderen Transaktionen zwischen 1. und 2. Einzahlung usw.

+0

Was Transaktionen dazwischen? –

+0

Es ist sehr unregelmäßig, doppelte ID-Werte in der Tabelle zu haben ... Gibt es einen echten "KEY"? Auch, was ist die Reihenfolge, Datum? –

+0

Der Schlüssel wäre Transaktions-ID, die ich oben nicht erwähnt habe. Die Reihenfolge ist zuerst nach ID, dann nach jeder ID nach Datum. – codeless

Antwort

3

Angenommen, Sie keine intervenierende Transaktionen:

select id, count(*) 
from (select t.*, 
      lead(transaction_type) over (partition by id order by date) as next_tt, 
      lead(transaction_type, 2) over (partition by id order by date) as next_tt_2, 
      lead(date, 2) over (partition by id order by date) as next_date_2 
     from t 
    ) t 
where transaction_type = 'deposit' and next_tt = 'deposit' and 
     next_tt_2 = 'withdrawal' and 
     next_date_2 < date + interval '7 day' 
group by id; 
+0

Was wäre, wenn es dazwischenliegende Transaktionen gäbe, zum Beispiel eine beliebige Anzahl von _anderen Transaktionen_ zwischen der ersten und der zweiten Einzahlung? – codeless

+1

@codeless. . . Das funktioniert immer noch. Sie würden nur einen 'where transaction_type '(' Einzahlung ',' Zurücknahme ')' in der Unterabfrage benötigen. –