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 小时?

Clickhouse - 矩阵逐项加法:如何对二维数组求和?

clickhouse 计算平均值

clickhouse

matlab如何实现间隔几秒钟读一次数据啊

Clickhouse:基于另一个数组的数组总和