Clickhouse 如何计算间隔总和 PAUSE -> UNPAUSE?
Posted
技术标签:
【中文标题】Clickhouse 如何计算间隔总和 PAUSE -> UNPAUSE?【英文标题】:Clickhouse howto calculate sum of intervals PAUSE -> UNPAUSE? 【发布时间】:2021-12-24 07:18:28 【问题描述】:几个月前,我尝试在 clickhouse 中分析数据,我喜欢它。它非常快。 今天我有一个用户日志。我需要计算每个用户的暂停时间总和。 我做什么: 我使用 where 选择一天的日志。并像这样接收表格:
time | user | event |
---|---|---|
2021-09-24 11:39:21 | user1 | PAUSE |
2021-09-24 11:39:21 | user2 | PAUSE |
2021-09-24 11:41:53 | user2 | UNPAUSE |
2021-09-24 11:41:53 | user1 | UNPAUSE |
对于每个用户,我有几个事件“暂停”和几个事件“取消暂停”。有时间和用户名。
有一个细微差别:有时我对每个用户都有 count(PAUSE) != count(UNPAUSE)。
我需要以秒为单位计算所有时间间隔的总和(PAUSE -> UNPAUSE) 我看到这样的结果表:
user | sum_pause_time |
---|---|
user1 | 345 |
user2 | 436 |
这是我的选择:
select
user,
sum_unpause - sum_pause as sum_pause_time
from
(
select
user,
sum(CASE
WHEN event == 'PAUSE' THEN toUnixTimestamp(time)
END) as sum_pause,
sum(CASE
WHEN event == 'UNPAUSE' THEN toUnixTimestamp(time)
END) as sum_unpause
from
queue_log_copy
where
toStartOfDay(time) >= (toStartOfDay(now()) - interval 1 day)
group by
user
)
但是有什么问题吗???? 请帮忙!
【问题讨论】:
【参考方案1】:您可以通过arrayMap方法计算PAUSE和UNPAUSE之间的差异,您只需要将值分组为数组。同样,如果我们检查先前的事件是否为 PAUSE 和当前的 UNPAUSE
(i > 1) AND (ex = 'UNPAUSE') AND ((e[i - 1]) = 'PAUSE')
一些检查的例子
CREATE TABLE test
(
`time` DateTime,
`user` Int64,
`event` String
)
ENGINE = Memory
insert into test values ('2021-09-24 11:39:21', 1, 'PAUSE')
insert into test values ('2021-09-24 11:39:21', 2, 'PAUSE')
insert into test values ('2021-09-24 11:41:53', 2, 'UNPAUSE')
insert into test values ('2021-09-24 11:41:53', 1, 'UNPAUSE')
insert into test values ('2021-09-24 11:43:53', 1, 'UNPAUSE')
SELECT *
FROM test
ORDER BY
user ASC,
time ASC
Query id: ed202dd9-fa74-40eb-9a18-d0582e7eaec6
┌────────────────time─┬─user─┬─event─┐
│ 2021-09-24 11:39:21 │ 1 │ PAUSE │
└─────────────────────┴──────┴───────┘
┌────────────────time─┬─user─┬─event───┐
│ 2021-09-24 11:41:53 │ 1 │ UNPAUSE │
└─────────────────────┴──────┴─────────┘
┌────────────────time─┬─user─┬─event───┐
│ 2021-09-24 11:43:53 │ 1 │ UNPAUSE │
└─────────────────────┴──────┴─────────┘
┌────────────────time─┬─user─┬─event─┐
│ 2021-09-24 11:39:21 │ 2 │ PAUSE │
└─────────────────────┴──────┴───────┘
┌────────────────time─┬─user─┬─event───┐
│ 2021-09-24 11:41:53 │ 2 │ UNPAUSE │
SELECT
user,
arraySum(arrayMap((tx, ex, i) -> if((i > 1) AND (ex = 'UNPAUSE') AND ((e[i - 1]) = 'PAUSE'), tx - (t[i - 1]), 0), t, e, arrayEnumerate(t))) AS sum
FROM
(
SELECT
user,
groupArray(toUnixTimestamp(time)) AS t,
groupArray(event) AS e
FROM
(
SELECT *
FROM test
ORDER BY
user ASC,
time ASC
)
GROUP BY user
)
Query id: 0d0e99f3-7a0f-4f5d-a1ce-9b89ef1275a8
┌─user─┬─sum─┐
│ 2 │ 152 │
│ 1 │ 152 │
└──────┴─────┘
【讨论】:
谢谢!我搜索arrayMap的文档。但它是如此之少。请给我几个链接。我想了解它是如何工作的。 这是一篇来自Altinity的好文章altinity.com/blog/…以上是关于Clickhouse 如何计算间隔总和 PAUSE -> UNPAUSE?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Clickhouse 中使用 group by 间隔 1 小时?