2016-12-02 3 views
2

Ich habe eine Datenmenge, die wie folgt aussieht:Relative row_number() in PostgreSQL

SessionID URL    created rownum 
abc www.google.com/page1 2016-08-01 1 
abc www.google.com/page2 2016-08-02 2 
abc www.google.com/blah  2016-08-03 3 
abc www.google.com/page3 2016-08-04 4 
abc www.google.com/page4 2016-08-05 5 

und ich möchte eine Ausgabe haben, die wie folgt aussieht:

SessionID URL    created rownum newrownum 
abc www.google.com/page1 2016-08-01 1 -2 
abc www.google.com/page2 2016-08-02 2 -1 
abc www.google.com/blah  2016-08-03 3 0 
abc www.google.com/page3 2016-08-04 4 1 
abc www.google.com/page4 2016-08-05 5 2 

Mit anderen Worten, ich würde gerne sehen, wo eine session eine bestimmte Seite blah besucht und ich möchte die Seiten vor und nach dieser bestimmten Seite besucht sehen. Beachten Sie, dass die Seiten in session nach dem Feld created bestellt werden.

I erzeugt die rownum Spalte die folgende Abfrage verwenden:

select 
    sessionid, 
    url, 
    created, 
    row_number() over(partition by sessionid order by created) as rownum 
from 
    <tablename> 
order by 
    sessionid, 
    created 

Ich bin nicht sicher, wie die Zeilennummern zu erhalten, die negative Werte in Bezug auf eine bestimmte Seite sind. Dies ist erforderlich, damit ich die Art der Seiten grafisch darstellen kann, die vor und nach der Seite blah besucht werden. Natürlich kann es mehrere Besuche auf derselben Seite blah in derselben Sitzung geben. In diesem Fall sollte der erste Besuch als der nullte Besuch behandelt werden (mit einem Wert 0 in der Spalte newrownum).

Antwort

3

Hier eine Methode enthält, ist:

select sessionid, url, created, rownum, 
     (rownum - min(case when url = 'blah' then rownum end) over (partition by sessionid) as newrownum 
from (select sessionid, url, created, 
      row_number() over (partition by sessionid order by created) as rownum 
     from <tablename> 
    ) t 
order by sessionid, created; 

Mit anderen Worten berechnet diese die Zeilennummer für 'blah' mit einer anderen Fensterfunktion. In neueren Versionen von Postgres können Sie das Schlüsselwort filter anstelle der case-Anweisung für die bedingte Min. Verwenden.

Hinweis: Dies ist der Offset vom ersten Auftreten von 'blah', wegen der min(). Das letzte Vorkommen würde max() verwenden. Und Ihre tatsächliche Logik könnte etwas wie url like '%blah' oder etwas mit dem vollständigen Pfadnamen verwenden.

+0

Vielen Dank für eine einfache Antwort, es macht sehr viel Sinn. Lief wie am Schnürchen :). – Patthebug

2

Sie können das Rot von blah von der bereits berechneten rownum Spalte für jede Sitzung subtrahieren.

select t.*, rownum-max(case when url like '%blah%' then rownum end) over(partition by sessionid) newrownum 
from (
select 
    sessionid, 
    url, 
    created, 
    row_number() over(partition by sessionid order by created) as rownum 
from 
    <tablename> 
) t 
order by rownum 

Um die genaue Mustererkennung von url zu bekommen blah einen regulären Ausdruck, so etwas wie url ~ '.+/blah$'

1

Wenden Sie einen Offset basierend auf der Zeilennummer der Seite an, die Sie als Baseline verwenden möchten (Ihre Zeile 0). In diesem Fall könnten Sie ein neues Feld als rownum - 3 erstellen, um die gesuchten Werte zu erreichen.