2016-06-05 13 views
1

Ich habe die folgende Tabelle mit Studenteninformationen.Sequenz basierend auf dem Wert in der vorherigen Zeile und der aktuellen Zeile generieren

S_ID Group_ID Date Score 
12345 1   1/1/2015 1 
12345 1   2/1/2015 2 
12345 1   3/1/2015 4 
12345 1   4/1/2015 5 
12345 1   9/1/2015 3 
12345 1   10/1/2015 8 
12345 2   1/1/2015 2 
12345 2   2/1/2015 4 
12345 2   3/1/2015 6 

Ich möchte eine neue Tabelle für einige Schüler generieren, nachdem eine Sequenz Spalte hinzufügen, wie unten

S_ID Group_ID Date  Score Sequence 
12345 1   1/1/2015 1  1 
12345 1   2/1/2015 2  2 
12345 1   3/1/2015 4  3 
12345 1   4/1/2015 5  4 
12345 1   9/1/2015 3  3 
12345 1   10/1/2015 8  4 
12345 2   1/1/2015 2  2 
12345 2   2/1/2015 4  3 
12345 2   3/1/2015 6  4 

Regeln gezeigt:

  • Sequenz sollte für jede Kombination von S_ID erzeugt werden , Group_I
  • Für den ersten Datensatz entspricht die Sequenznummer dem Score
  • 2. Satz ab, dies ist 1 + die vorherige Folgenummer
  • Wenn die Differenz zwischen dem Datum der vorherigen Zeile und der aktuellen Zeile mehr als 100 Tage ist, wird die Sequenznummer neu gestartet (wie ) notieren)

Dies ist eine große Tabelle, und ich bin auf der Suche nach der optimierten SQL. Jede Hilfe würde sehr geschätzt

Antwort

0

Der Trick hier ist zu finden, wo die Sequenznummern neu beginnen. Dies ist für neue Studenten, Gruppen und wenn das vorherige Datum eine zu große Lücke hat. Für Letzteres können Sie lag() verwenden, um ein "Startdatum-Flag für neue Daten" zu berechnen und dann aggregieren, um eine Gruppierung zu erhalten.

select t.*, 
     (first_value(score) over (partition by s_id, group_id, grp order by date) + 
     row_number() over (partition by s_id, group_id, grp order by date) - 1 
     ) as sequence 
from (select t.*, 
      sum(case when prev_date is null or prev_date < date - 100 
         then 1 else 0 
       end) over (partition by s_id, group_id order by date) as grp 
     from (select t.*, 
        lag(date) over (partition by s_id, group_id order by date) as prev_date 
      from t 
      ) t 
    ) t; 
+0

Danke. Das scheint gut zu funktionieren. –

Verwandte Themen