2016-11-18 74 views
0

我有一個連接日誌表供客戶在我們的數據庫中使用,我試圖每天都計算每個客戶在過去七天內的連接數。我使用的源表中有我想要的爲輸出計算過去X天的會話數

uuid, _date, total_connections_over_trailing_seven_days, 

,這樣我可以爲一個給定的客戶賬戶和給定的日期,看看有多少次這個人的

uuid, sessionuid, connection_timestamp 

架構在過去的幾天中已經連接了七次(或其他)。

我寫來完成,這查詢

SELECT 
    uuid, 
    connection_timestamp::date as _date, 
    COUNT(sessionuid) OVER (ORDER BY timestamp_session ROWS 6 PRECEDING) as trailing_seven_day_session_count 
FROM connection_history_table 

但是,當我執行這個查詢,我得到每個用戶單獨的行,並在源表而不是單個記錄每connection_timestamp爲每一個獨特connection_timestamp ::日期。此外,trailing_seven_day_session_count中的值從1增加到最大值7(如果某一天至少​​有7個會話),但在此之後不會增加。因此,我似乎在計算特定日期的會話數量,但僅限於前7次會話。

uuid  _date    trailing_seven_day_session_count 
16398 2015-02-18 00:00:00 1 
16398 2015-02-18 00:00:00 2 
16398 2015-02-18 00:00:00 3 
16398 2015-02-18 00:00:00 4 
16398 2015-02-18 00:00:00 5 
16398 2015-02-18 00:00:00 6 
16398 2015-02-18 00:00:00 7 
16398 2015-02-18 00:00:00 8 
16398 2015-02-18 00:00:00 8 
16398 2015-02-25 00:00:00 1 
16398 2015-02-25 00:00:00 2 
16398 2015-02-25 00:00:00 3 
16398 2015-02-25 00:00:00 4 
16398 2015-02-25 00:00:00 5 
16398 2015-02-25 00:00:00 6 
16398 2015-02-25 00:00:00 7 
16398 2015-02-25 00:00:00 8 
16398 2015-02-25 00:00:00 8 

我是使用窗口函數的新手,我不清楚我在這裏做的不正確。我已經嘗試通過connection_timestamp :: date做一個分區,但這也沒有幫助。我基本上在抓秸稈,並且這樣做不成功。

感謝, 布拉德

回答

1

也許你需要計算每一天的會議,然後做的前幾天的總和。類似這樣的:

select 
    uuid, 
    day, 
    sum(sessions) over (partition by uuid order by day rows 6 preceding) as trailing_seven_day_session_count 
from (select uuid, connection_timestamp::date as day, count(*) sessions 
    from connection_history_table 
    group by 1,2) 
order by 1,2 

關於Brad對稀疏數據的評論,這裏有一種可能的方法。它會生成零記錄以填滿日期,因此回顧一組記錄將與日期相關。沒有跑過這個,但它應該非常接近。由於它會產生數天,因此需要調整整個時間範圍。我不確定我是否獲得了日期範圍和填充權限......它試圖獲得37天的數據來生成30天的記錄。

with days as (
    -- hack to generate days in redshift like a generate_series function 
    select (dateadd(day, -row_number() over (order by true), sysdate::date)) as day 
      from stv_blocklist limit 37 
), 
day_counts as (
    select uuid, connection_timestamp::date as day, count(*) sessions 
    from connection_history_table 
    where connection_timestamp >= sysdate-37 
    group by 1,2 
), 
zero_days as (
    select s.uuid, d.day, 0 as sessions 
    from (
     select distinct uuid from connection_history_table 
     where connection_timestamp >= sysdate-37 
    ) s 
    cross join days d 
) 
select 
    uuid, 
    day, 
    sum(sessions) over (partition by uuid order by day rows 6 preceding) as trailing_seven_day_session_count 
from (
    select uuid, day, sessions from day_counts 
    union all 
    select uuid, day, sessions from zero_days z 
     left join day_counts c on z.uuid=c.uuid and z.day=c.day 
     where c.uuid is null 
) 
having day >= sysdate-30 
order by 1,2 
+0

是的,我試過類似的東西,但它沒有得到我想要的,因爲它計數了前面的六行,而且我不一定每天都有一排。我每天只有一行用戶玩過。所以我必須想出一個完全不同的解決方案。儘管感謝您的幫助。我打算升級您的解決方案並接受它,因爲它解決了我發佈的原始問題,而不是我實際遇到的問題。 : –

+0

它是否必須是一次性鏡頭或可以迭代運行查詢......每天說一次?如果你每天都可以做,你可以在內部select中添加一個where子句,它只選擇connection_timestamp> = sysdate-7的記錄來獲得你想要的。 – systemjack

+0

增加了janky查詢來處理空日。 – systemjack