如何在 Clickhouse 中生成子组的聚合结果?

问题描述 投票:0回答:1

我希望能够有效地从 clickhouse 表中生成聚合结果以及带有子组的数组排序

那么,让我举个例子吧

比如说,我有以下示例表

专栏 类型
id 字符串
客户 字符串
v1 国际
v2 国际
什么时候 日期时间

从简单的聚合查询开始,比如

SELECT id, AVG(v1) AVG1, SUM(v2) SUM2 FROM table WHERE When > today() GROUP BY id
这会产生类似的东西

身份证 AVG1 SUM2
1 100 300
2 200 400
... ... ...

我想用这样的东西扩展结果

身份证 平均 SUM2 每个客户端的行数
1 100 300 [{AVG1:110, SUM2:150},{AVG1:90, SUM2:50},{AVG1:100, SUM2:100}]
2 200 400 [{200, 100},{200, 300},{200, 0}]
... ... ... [...]

rows per client
字段使用与主查询相同的过滤器进行聚合,但也对其结果应用了额外的分组依据

我很好奇,如果这样的事情在 Clickhouse 中是可能的(如果是的话,最有效的方法是什么),或者我是否必须使用 Join,然后以编程方式解析结果?

联接是迄今为止我设法完成的最好的,但生成的查询并不是最佳的,因为我必须选择相同的数据两次(注意,我使用的表和查询确实是示例性的,而真实的查询有更多的字段和更复杂的聚合),并且结果与我想要完成的不太一样

aggregate-functions clickhouse
1个回答
2
投票
create table I_AM_TIRED_TO_WRITE_EXAMPLES_WHY_ARE_YOU_SO_LAZY(
  id    String,
  client    String,
  v1    Int,
  v2    Int,
When    DateTime) Engine=Memory;

insert into I_AM_TIRED_TO_WRITE_EXAMPLES_WHY_ARE_YOU_SO_LAZY
select number, arrayJoin(['client1', 'client2', 'client3']),
     number%10, number%3, today()
from numbers(15);


SELECT
    id,
    avgMerge(AVG1s) AS AVG1,
    sum(SUM2s) AS SUM2,
    CAST(groupArray((client, (finalizeAggregation(AVG1s), SUM2s))), 'Map(String, Tuple(avg Float64, sum Int64))') AS r
FROM
(
    SELECT
        id,
        client,
        avgState(v1) AS AVG1s,
        SUM(v2) AS SUM2s
    FROM I_AM_TIRED_TO_WRITE_EXAMPLES_WHY_ARE_YOU_SO_LAZY
    WHERE When >= today()
    GROUP BY
        id,
        client
)
GROUP BY id
ORDER BY id ASC

┌─id─┬─AVG1─┬─SUM2─┬─r─────────────────────────────────────────────────┐
│ 0  │    0 │    0 │ {'client2':(0,0),'client3':(0,0),'client1':(0,0)} │
│ 1  │    1 │    3 │ {'client1':(1,1),'client2':(1,1),'client3':(1,1)} │
│ 10 │    0 │    3 │ {'client3':(0,1),'client2':(0,1),'client1':(0,1)} │
│ 11 │    1 │    6 │ {'client3':(1,2),'client2':(1,2),'client1':(1,2)} │
│ 12 │    2 │    0 │ {'client2':(2,0),'client3':(2,0),'client1':(2,0)} │
│ 13 │    3 │    3 │ {'client2':(3,1),'client3':(3,1),'client1':(3,1)} │
│ 14 │    4 │    6 │ {'client3':(4,2),'client2':(4,2),'client1':(4,2)} │
│ 2  │    2 │    6 │ {'client1':(2,2),'client3':(2,2),'client2':(2,2)} │
│ 3  │    3 │    0 │ {'client3':(3,0),'client2':(3,0),'client1':(3,0)} │
│ 4  │    4 │    3 │ {'client1':(4,1),'client3':(4,1),'client2':(4,1)} │
│ 5  │    5 │    6 │ {'client3':(5,2),'client2':(5,2),'client1':(5,2)} │
│ 6  │    6 │    0 │ {'client2':(6,0),'client3':(6,0),'client1':(6,0)} │
│ 7  │    7 │    3 │ {'client1':(7,1),'client2':(7,1),'client3':(7,1)} │
│ 8  │    8 │    6 │ {'client3':(8,2),'client2':(8,2),'client1':(8,2)} │
│ 9  │    9 │    0 │ {'client1':(9,0),'client3':(9,0),'client2':(9,0)} │
└────┴──────┴──────┴───────────────────────────────────────────────────┘

groupArrayMap:https://fiddle.clickhouse.com/383cb12c-0039-401c-a514-1eb333ae5720

© www.soinside.com 2019 - 2024. All rights reserved.