[英]Count in time window for each present day in Clickhouse
我有一張表,其中包含使用某些服務的用戶的日志。 類似於下表,每一行都是活動的時間戳和用戶 ID。
用戶身份 | 時間戳 |
---|---|
831 | 2022-06-22 04:37:10 |
789 | 2022-06-22 12:38:57 |
831 | 2022-06-22 16:40:10 |
我想計算每天的唯一用戶數,但不僅僅是那天,還包括一周前。 基本上,移動 window 唯一計數:對於“x”天,計數應該在“x-7 天”的 window 中:“x”。
正如我在文檔中看到的那樣,
DateTime RANGE OFFSET 幀的 INTERVAL 語法:不支持,改為指定秒數(RANGE 適用於任何數字類型)。
不支持使用間隔傳遞類似RANGE INTERVAL 7 day PRECEDING
之類的簡單方法,他們建議使用 range with passing seconds,但我真的沒有 sql 中的范圍經驗,所以我真的不知道該怎么做你在那里過了幾秒鍾。 我當前的代碼:
with cleaned_table as (
select
user_id,
date_trunc('day', timestamp) as day
from
table
)
SELECT
day,
uniqExact(user_id) OVER (
PARTITION by day ORDER BY day range ???
)
FROM
cleaned_table
另外,理想情況下,我覺得我應該在某個地方添加group by
因為我每天只需要一行,而不是初始表中每一行的一行,並且沒有分組我正在對每一行進行重新計算(?)每天計算一次。
我會將此標記為答案,但如果有人知道如何通過合並group by
或其他方法來優化此解決方案而不為每一行重新計算 window function 並且每天只計算一次,我會很高興。
無論如何, RANGE BETWEEN 6 PRECEDING and current row
是我正在尋找的,工作得很好。 還添加了::date
以將時間戳轉換為 date dtype,並且DISTINCT day
允許直接為每一天選擇一行,而不是再運行group by
any
時間。
with cleaned_table as (
select
user_id,
date_trunc('day', timestamp)::date as day
from
table
)
SELECT
DISTINCT day,
uniqExact(user_id) OVER (
ORDER BY
day ASC RANGE BETWEEN 6 PRECEDING
and current row
) as users
FROM
cleaned_table
create table t(user_id Int64, timestamp DateTime) Engine = Memory as select * from values((831, '2022-06-22 04:37:10'), (789,'2022-06-22 12:38:57'), (831,'2022-06-22 16:40:10'), (1,'2022-06-21 12:38:57'), (2,'2022-06-20 16:40:10'));
SELECT
day,
finalizeAggregation(u) AS uniqByDay,
uniqMerge(u) OVER (ORDER BY day ASC RANGE BETWEEN 6 PRECEDING AND CURRENT ROW) AS uniqBy6Days
FROM
(
SELECT
toDate(timestamp) AS day,
uniqState(user_id) AS u
FROM t
GROUP BY day
)
ORDER BY day ASC
┌────────day─┬─uniqByDay─┬─uniqBy6Days─┐
│ 2022-06-20 │ 1 │ 1 │
│ 2022-06-21 │ 1 │ 2 │
│ 2022-06-22 │ 2 │ 4 │
└────────────┴───────────┴─────────────┘
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.