clickhouse自定义函数的困惑

近期遇到一个困惑的问题,自定义函数中,如果出现查询语句,则传递的参数,不能传递字段名,只能传递常量或者表达式,文档中也没有找到对应的解决办法。

需求其实比较简单,查询的时候,要做一个"少数服从多数"的决定,在一行记录中,存在多个字段值是String类型,使用哪个字段值,取决于字段内容出现的频率次数最高的字符串,注意,这里是一行记录,可以理解成,一个数组字段类型,常规想法就是 select group by ,但是,就出现了开头说的问题,不能传递字段名称作为参数。

sql 复制代码
CREATE function my_count as (str1 ,str2 ,str3 )-> (
	SELECT max(element)
	from
	( 
	    SELECT
	    arrayJoin(array) AS element,
	    count(*) AS count
		FROM (
		    SELECT [str1,str2,str] AS array
		)
		where LENGTH(element)>0
		GROUP BY element
		ORDER BY count DESC
		limit 1
	) t	
)

上述代码,传递常量是没有问题的,但是:

select my_count(field1,field2,field3) as a from my_table

就会报错,提示不支持字段作为参数

后来,只能从文档的方法来入手,找内置的arry相关函数

CREATE FUNCTION my_test as (arr) ->arrayReverseSort((m,n)->n, arrayMap(x->(x,countEqual(arr,x)),arrayDistinct(arr)))

这里就很好解决了需求,不过,性能可能会低一点,起码先凑合着用着。

arrayDistinct 表示数组的元素取唯一,去重。

countEqual 表示计算元素在数组中出现的次数

arrayMap 把统计元素个数映射成 (key,count)的格式,其中count就是计数

arrayReverseSort 就是倒序,根据第2个参数(count)进行排序

在使用中 SELECT uniqTotal('a','b','b','a','a')1.1 AS ele

其中1表示取数组的第一个元素,.1表示取key值,就是需求目标

完美解决,如果有更好的办法,麻烦留言告知,谢谢!

相关推荐
zhoupenghui16817 天前
ClickHouse merge引擎详解以及应用
数据库·clickhouse·merge·mergetree
ClickHouseDB18 天前
ClickHouse 十年开源,今非昔比!
clickhouse·开源·apache
ClickHouseDB19 天前
ClickHouse 开源十年:数据分析领域的中流砥柱
clickhouse·数据分析·开源
java_logo23 天前
Docker Compose 部署 ClickHouse:快速搭建高性能列式数据库
数据库·clickhouse·docker·列式数据库·轩辕镜像·高性能数据库·clickhouse部署教程
ClickHouseDB24 天前
TPC-H 成本不到一分钱:ClickHouse Cloud 对比 Snowflake、Databricks、BigQuery 和 Redshift
clickhouse
隔壁阿布都1 个月前
ClickHouse完整指南
服务器·数据库·clickhouse
数据库小学妹1 个月前
MySQL做报表太慢?引入ClickHouse列式存储,同一个查询快240倍
mysql·clickhouse·列式存储·分析型数据库·向量化执行·olap数据库·mysql对比
ClickHouseDB1 个月前
推出 ClickHouse Cloud 中的多阶段分布式查询执行
分布式·clickhouse
weixin_307779131 个月前
Linux下ClickHouse数据仓库故障系统化诊断脚本
linux·运维·clickhouse·自动化·数据库开发
SelectDB技术团队1 个月前
Agent 场景动态 JSON 性能拆解:Apache Doris 比 ClickHouse 快 7 倍、比 Elasticsearch 快 2 倍
数据库·clickhouse·elasticsearch·json·apache·日志分析·apache doris