跳转到主要内容

简介

ClickHouse 没有 PIVOT 运算符,但我们可以借助聚合函数组合器,尤其是带有 -Map 后缀的组合器,实现类似的效果。 本文将介绍具体做法。 另外,还有一个涵盖相同内容的视频,你可以在下方观看:

理解聚合函数组合器

我们先从一个简单的示例开始。我们将使用 clickhouse-local,可通过运行以下命令启动它:
以下查询调用了 sumMap 函数,该函数接受一个 Map,并对其中每个键的值求和:
这个示例没什么特别意思,因为它返回的就是我们传入的同一个 Map。 现在我们来对多行 Map 调用 sumMap
ClickHouse 在两行中都出现了,因此它对应的值被求和了。键 ClickBench 只在一行中出现,因此只对单个值求和,结果就是该值本身! 我们也可以使用 maxMap 来找出每个键的最大值:
或者,我们可以使用 avgMap 来计算每个键的平均值:
希望这能让你大致了解这些函数组合器的工作方式。

实际应用:英国房价数据集

现在,我们要在更大的数据集上,在 ClickHouse SQL playground 中使用这些方法。 我们可以使用 clickhouse-client 连接到 playground:
我们将查询 uk_price_paid 表,先来看看该表中的数据:
从上文可以看出,该表包含英国房产销售相关的各种字段。

按十年期分组并聚合

接下来,我们来计算数据集中每个十年期内按郡分组的房价中位数:

过滤结果

我们可以对结果进行过滤,只保留 2010 年及之后的数据:

组合多个聚合操作

如果我们想找出每个十年的最高价格,可以使用前面提到的 maxMap 函数:

对 map 值应用函数

或者,我们也可以使用 avgMap 来计算平均价格。 这些值的小数位很多,我们可以使用 mapApply 函数,对 map 中的每个值调用 floor 函数来将其向下取整,从而让结果更简洁:

灵活分组:郡、行政区和邮政编码

我们来尝试按一些不同的字段分组。 这次我们将按郡和行政区分组,计算每个十年的房价中位数:
我们也可以选择按年份分组,再在 map 中拼接 postcode1postcode2
最后修改于 2026年7月3日