2015-10-13 64 views
0

與psql我想統計每個唯一訪問者。如何通過動態時間間隔聚合數據

一位獨特的訪問者是一位訪問者,他在一個小時前還沒有訪問過。

因此,對於以下用戶行和時間戳,我們會得到4個唯一訪問者的總數,其中user1和user2分別計爲2。

請注意,我不想在24小時內每小時彙總一次。我想在用戶第一次訪問時間戳之後的一小時內彙總。

我猜sql直線表達式不會這樣做。

user1,"2015-07-13 08:28:45.247000" 
user1,"2015-07-13 08:30:17.247000" 
user1,"2015-07-13 09:35:00.030000" 
user1,"2015-07-13 09:54:00.652000" 
user2,"2015-07-13 08:28:45.247000" 
user2,"2015-07-13 08:30:17.247000" 
user2,"2015-07-13 09:35:00.030000" 
user2,"2015-07-13 09:54:00.652000" 

因此user1到達8點28分,這被視爲一擊。他在8點30分返回,計爲零。然後他在9點35分回來,這是從8點30分開始的一個多小時,所以他又受到了重創。然後他在9:35回來,這距離上次9:30只有5分鐘,所以這個計數爲零。用戶1總共有2次點擊。同樣的事情發生,對於user2意義兩支安打各將其帶到一個最終的總的4

+0

'現在想'應該是'不想'我想?請始終聲明您的Postgres版本。你有單獨的用戶表嗎?實際的表定義將有助於查看數據類型和約束:CREATE TABLE腳本或psql中的\ d tbl'的輸出。對於每60分鐘訪問一次的假設用戶呢?計數爲** 0次訪問總數,即使在較長時間內也是如此?此外,嚴格來說,您的定義將在不到一小時前(從現在開始)排除訪問。 –

+0

該版本是亞馬遜上的Redshift。所以它缺少某些postgres功能。如果用戶每60分鐘訪問一次,則每次訪問計數一次。如果用戶在60分鐘內訪問超過一次,那麼他只會計算一次。 –

+0

紅移不是Postgres,也非常有限。我不是粉絲。請記住提供您的版本,以問題開頭。 –

回答

2

這裏有一個方法:

select count(*) 
from t 
where not exists (select 1 
        from t t2 
        where t2.user = t.user and 
         t2.timestamp < t.timestamp and 
         t2.timestamp > t.timestamp - interval '1 hour' 
       ); 

編輯:

如果有相同的時間戳是一個潛在的問題,您可以使用count(distinct user, timestamp)

注意:usertimestamp都是關鍵字,user是保留的。希望你的實際列被命名爲別的東西。

where子句只保留在前一小時沒有其他用戶記錄的記錄。這是您對「新」用戶的定義,因此彙總計數應該是您要查找的內容。

+0

非常感謝。你能解釋它在做什麼嗎?這將是非常有益的。 –

+0

我誤解了這個定義。它改變了定義。我提高了你的意思,並重新定義了這個定義,但是現在答案也是不正確的。 –

+0

@BrianYeh。 。 。我第一次明白了這個問題。這應該得到你想要的數量。 –

1

角的情況下在你的定義一邊(see comment),這個查詢比我的本地測試提供了一個@Gordon上的Postgres 9.4快許多倍,帶或不帶指數:

SELECT count(ct) 
FROM (
    SELECT user_id, CASE WHEN lead(created_at, 1, 'infinity') 
         OVER (PARTITION BY user_id ORDER BY created_at) 
       > created_at + interval '1h' THEN true ELSE NULL END AS ct 
    FROM tbl 
    ) sub; 

的核心特性是窗口功能lead()查找當前用戶的「下一個」行。如果下一行是更多比一個小時的路程,這一行很重要。

lead()經常被忽視的功能是爲缺少的行提供默認值。填寫'infinity'覆蓋角落案例。

此查詢適用於timestampcreated_at中的NULL值(未計數)或重複值(僅1行計數)。

關鍵最高性能是多列索引

CREATE INDEX tbl(user_id, created_at); 

對於「獨立訪問者」防彈定義不同的查詢方式可能更好。

+0

如果user1在9:00訪問,那麼在9:30訪問然後在11:00訪問,那麼這應該算作2次訪問。我嚴格地表述了這個定義。我會提高你們兩個人並編輯定義。 –