2016-12-02 46 views
2

我有一個數據集,看起來像這樣:相對ROW_NUMBER()在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 

,我想有一個輸出看起來像這樣:

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 

換句話說,我希望看到session正在訪問特定頁面blah,我希望看到在此特定頁面之前和之後訪問的頁面。請注意,session中的頁面按照created字段進行排序。

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

我不知道如何獲取相對於某一頁負值行號:

我使用下面的查詢產生的rownum列。這是必需的,所以我可以繪製頁面blah前後訪問的頁面種類。當然,可以在同一個會話中對同一頁面blah進行多次訪問。在這種情況下,應將第一次訪問視爲第零次訪問(newrownum列中的值爲0)。

回答

3

這裏的東西是一個方法:

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; 

換句話說,這個計算的行數'blah'使用另一個窗口函數。在最新版本的Postgres中,您可以使用filter關鍵字而不是case語句作爲條件最小值。

注意:由於min()的原因,這與第一次出現'blah'時的偏差。最後一次使用max()。而且,你的實際邏輯可能會使用類似url like '%blah'之類的東西或者完整的路徑名。

+0

非常感謝您提供了一個簡單的答案,它非常有意義。工作就像一個魅力:)。 – Patthebug

2

您可以從每個會話的已經計算出的rownum列中減去blah的rownum。

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 

獲取包含blah使用正則表達式的URL的確切模式匹配,就像url ~ '.+/blah$'

1

根據要用作基準的頁碼的行號(行0)應用偏移量。在這種情況下,您可以創建一個新的字段作爲rownum - 3以實現您正在查找的值。