【问题标题】:Clickhouse Aggregate data from one table into other tableClickhouse 将一张表中的数据聚合到另一张表中
【发布时间】:2020-07-08 04:46:46
【问题描述】:

我正在尝试解决这个问题:

给定一个 input_table

> app_name, user_id, state, timestamp \
> App1 ,   user1   , open,  1 \
> App1 ,   user1   , close, 2 \
> App2 ,   user2   , open,  3 \
> App1 ,   user4   , open,  4 \
> App2 ,   user3   , open,  5 

我想使用 MV 来更新用户和应用程序状态映射,如下面的 output_table

> App1 , [user4] -- user1 is closed \
> App2 , [user2, user3]

output_table 应在数据插入 input_table 后立即更新。

当我在 input_table 中有传入数据时:

> App1, user5, open, 6 \
> App1, user1, open, 7

输出表应该是这样的:

> App1 , [user4, user5, user1] \
> App2 , [user2, user3]

我有一个非常幼稚的解决方案版本,但它是批量更新并且需要表扫描数据来重建映射。 有什么方法可以在很短的一段时间后部分完成,或者通过插入的每一行进行更新。我认为 Materialize View 可以提供帮助,但我不确定每次在 input_table 中插入时要更新的输出表

【问题讨论】:

    标签: sql view aggregate materialize clickhouse


    【解决方案1】:

    当您执行 GroupBy 时,如果您在 delta 事务中执行,结果数据集将应用于该 delta 部分,而不是整个数据,因此如果您的数据不是很大,最好的方法是在整张表如下

    SELECT app_name, GROUP_CONCAT(user_id) AS combined
    FROM T
    GROUP BY app_name
    

    【讨论】:

      【解决方案2】:

      在使用物化视图之前,我建议对原始数据使用查询。为了加快查询速度,请考虑在 WHERE 子句中定义日期范围。

      SELECT app_name, groupArray(user_id) users
      FROM (
        SELECT app_name, user_id, argMax(state, timestamp) last_state
        FROM input_table
        WHERE timestamp BETWEEN 1 AND 11 /* <-- restrict the date range */
        GROUP BY app_name, user_id
        HAVING last_state != 'close')
      GROUP BY app_name
      
      /* result for 1st dataset
      ┌─app_name─┬─users─────────────┐
      │ App1     │ ['user4']         │
      │ App2     │ ['user3','user2'] │
      └──────────┴───────────────────┘
      */
      

      如果此查询运行缓慢,则需要使用聚合物化视图

      【讨论】:

        猜你喜欢
        • 2021-12-02
        • 1970-01-01
        • 1970-01-01
        • 2023-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多