## 高阶函数
高阶函数、`->`运算符和 lambda(params, expr) 函数
[https://clickhouse.tech/docs/en/sql-reference/functions/](https://clickhouse.tech/docs/en/sql-reference/functions/)
高阶函数只能接受 lambda 函数作为它们的函数参数。要将 lambda 函数传递给高阶函数,请使用`->`运算符。箭头左侧有一个形参,它是任意 ID,或多个形参——元组中的任意 ID。箭头右侧有一个表达式,可以使用这些形式参数,以及任何表格列。
例子:
~~~
x -> 2 * x
str -> str != Referer
~~~
接受多个参数的 lambda 函数也可以传递给高阶函数。在这种情况下,高阶函数会传递几个长度相同的数组,这些数组将对应于这些参数。
对于某些函数,可以省略第一个参数(lambda 函数)。在这种情况下,假定映射相同。
## 数组函数
文档:[https://clickhouse.tech/docs/en/sql-reference/functions/array-functions/](https://clickhouse.tech/docs/en/sql-reference/functions/array-functions/)
* arrayConcat
![](https://img.kancloud.cn/a9/04/a904d1731829d4685f21210fddbbe257_527x159.png)
* arrayElement(arr,n)
![](https://img.kancloud.cn/1f/5c/1f5c3ea432ae89a68985d60547de98a8_467x189.png)
* has(arr,elem)
检查’arr’数组是否具有’elem’元素。
如果元素不在数组中,则返回0;如果在,则返回1。
![](https://img.kancloud.cn/b3/69/b36967040ce1ecf5d13fd761b91c6891_512x192.png)
* indexOf(arr, x)
如果它在数组中,则返回第一个 'x' 元素的索引(从 1 开始),否则返回 0。
![](https://img.kancloud.cn/dd/e9/dde9748b5ebad516083ca19ca68e3efa_512x187.png)
* arrayCount(高阶函数)
返回 arr 数组中 func 返回非 0 的元素数。如果未指定 'func',则返回数组中非零元素的数量。
![](https://img.kancloud.cn/72/fe/72fece7b8c4e541733032b4e3c386812_567x375.png)
* countEqual(arr, x)
返回数组中等于 x 的元素数。
![](https://img.kancloud.cn/8c/bb/8cbbc666a25d0f9c16ff5d16776f8e81_516x185.png)
* arrayEnumerateUniq(arr, ...)
返回一个与源数组大小相同的数组,指示每个元素在具有相同值的元素中的次数
此函数在使用 ARRAY JOIN 和数组元素聚合时很有用。
![](https://img.kancloud.cn/e2/7e/e27e0778cf136f1e19fcfdf1f2be9173_640x193.png)
* arrayPopBack
从数组中删除最后一项
![](https://img.kancloud.cn/91/c6/91c6788e3108c1fa0f159fc178873b6a_637x185.png)
* arrayDistinct
数组去重
![](https://img.kancloud.cn/27/52/2752bd487c4d8bb6a054aa0a869cb118_568x192.png)
* arrayFilter(func, arr1, …)(高阶函数)
返回func过滤的元素
![](https://img.kancloud.cn/9b/49/9b4949749819703b4aaf155d1d4f5295_701x189.png)
* arrayMap(func, arr1, ...)(高阶函数)
返回从`func`函数的原始应用中获得的数组到`arr`数组中的每个元素。
![](https://img.kancloud.cn/7c/a3/7ca33cd13a4f78a0595134d3bf05703f_523x187.png)
* arrayJoin(arr)
![](https://img.kancloud.cn/62/08/6208260e0c84cb09f91c5b6041bbf93d_644x299.png)
## 类型转换
文档:[https://clickhouse.tech/docs/en/sql-reference/functions/type-conversion-functions/](https://clickhouse.tech/docs/en/sql-reference/functions/type-conversion-functions/)
* toInt(8|16|32|64|128|256)
将输入值转换为数据类型。
~~~
SELECT toInt64(nan), toInt32(32), toInt16('16'), toInt8(8.8);
~~~
* toInt(8|16|32|64|128|256)OrZero
失败返回0
~~~
SELECT toInt64OrZero('123123'), toInt8OrZero('123qwe123');
~~~
* toInt(8|16|32|64|128|256)OrNull
失败返回null
~~~
SELECT toInt64OrNull('123123'), toInt8OrNull('123qwe123');
~~~
* toString
转换为字符串或从字符串转换时,来格式化或解析值。
* CAST(x, T)
将’x’转换为’t’数据类型。还支持语法CAST(x AS t)
## 字符串函数
文档:[https://clickhouse.tech/docs/en/sql-reference/functions/string-functions/](https://clickhouse.tech/docs/en/sql-reference/functions/string-functions/)
* empty
* notEmpty
* length
* splitByChar
返回拆分后的子串的数组。 如果分隔符出现在字符串的开头或结尾,或者如果有多个连续的分隔符,则将在对应位置填充空的子串。
![](https://img.kancloud.cn/64/42/644225f29e6d992374a26bcbf844a543_521x193.png)
* splitByString(separator, s)
与上面相同,但它使用多个字符的字符串作为分隔符。 该字符串必须为非空。
![](https://img.kancloud.cn/8f/56/8f5603f87d991d4c58ff1f7c47baffe1_559x215.png)
## json函数
文档:[https://clickhouse.tech/docs/en/sql-reference/functions/json-functions/](https://clickhouse.tech/docs/en/sql-reference/functions/json-functions/)
* visitParamHas(params, name)
![](https://img.kancloud.cn/1b/78/1b784d895d1dc3434a939806db39a308_499x197.png)
* visitParamExtractRaw(params, name)
返回字段的值,包括分隔符。
![](https://img.kancloud.cn/84/c1/84c1a9523cb2bb206ec5e4a3d5fbddf8_559x182.png)
解析双引号中的字符串,这个值没有进行转义。如果转义失败,则返回一个空字符串。
* visitParamExtractString(params, name)
解析 JSON 并提取字符串。这个函数类似于`visitParamExtractString`函数。
![](https://img.kancloud.cn/3b/aa/3baab4c9bba50da383f182035aa96b0c_583x202.png)
* JSONHas(json\[, indices\_or\_keys\]…)
如果JSON中存在该值,则返回`1`。
如果该值不存在,则返回`0`。
![](https://img.kancloud.cn/88/4a/884a2cb6ba76bcf1ff13545aade988b0_646x188.png)
* JSONExtract(json\[, indices\_or\_keys…\], Return\_type)
解析 JSON 并提取给定 ClickHouse 数据类型的值。
~~~
SELECT JSONExtract ('{"a": "hello", "b": [-100, 200.0, 300],"c":1}', 'c', 'Int64') AS value
~~~
![](https://img.kancloud.cn/1c/0d/1c0d3b268312d8048c704d3d8376371e_815x205.png)
~~~
-- 创建表
create table tb_json(cont String) engine=Memory;
-- 插入数据
insert into tb_json values
('{"movie":"1207","rate":"4","timeStamp":"978300719","uid":"1"}'),('{"movie":"2028","rate":"5","timeStamp":"978301619","uid":"1"}')
,('{"movie":"531","rate":"4","timeStamp":"978302149","uid":"1"}'),('{"movie":"3114","rate":"4","timeStamp":"978302174","uid":"1"}'),('{"movie":"608","rate":"4","timeStamp":"978301398","uid":"1"}');
SELECT cast(JSONExtract(cont, 'Tuple(String, String)').2,'Float64') from tb_json
~~~
![](https://img.kancloud.cn/c7/e0/c7e089cd0fb597362671f6ef009ee7aa_676x265.png)
* JSONExtractKeysAndValues(json\[,indices\_or\_keys…\],Value\_type)
从 JSON 解析键值对,其中值是给定的 ClickHouse 数据类型。
~~~
SELECT JSONExtractKeysAndValues('{"x": {"a": 5, "b": 7, "c": 11}}', 'x', 'Int8') = [('a',5),('b',7),('c',11)];
~~~
![](https://img.kancloud.cn/e7/fc/e7fceb4224c7c9f0ab8ef2d864c019c1_812x468.png)
## 漏斗模型链路函数
案例:
漏斗模型:分析用户行为
![](https://img.kancloud.cn/1b/5c/1b5ce3e8ae34a60984d386e257542df1_1080x628.png)
此类场景clickhouse提供了一个名叫windowFunnel的函数来实现
~~~SQL
-- 创建一张用户行为表,至少包含时间、事件、用户id
CREATE TABLE test.action
(
`uid` Int32,
`event_type` String,
`time` datetime
)
ENGINE = MergeTree()
PARTITION BY uid
ORDER BY xxHash32(uid)
SAMPLE BY xxHash32(uid)
SETTINGS index_granularity = 8192
-- 插入数据
insert into action values(1,'浏览','2020-01-02 11:00:00');
insert into action values(1,'点击','2020-01-02 11:10:00');
insert into action values(1,'下单','2020-01-02 11:20:00');
insert into action values(1,'支付','2020-01-02 11:30:00');
insert into action values(2,'下单','2020-01-02 11:00:00');
insert into action values(2,'支付','2020-01-02 11:10:00');
insert into action values(1,'浏览','2020-01-02 11:00:00');
insert into action values(3,'浏览','2020-01-02 11:20:00');
insert into action values(3,'点击','2020-01-02 12:00:00');
insert into action values(4,'浏览','2020-01-02 11:50:00');
insert into action values(4,'点击','2020-01-02 12:00:00');
insert into action values(5,'浏览','2020-01-02 11:50:00');
insert into action values(5,'点击','2020-01-02 12:00:00');
insert into action values(5,'下单','2020-01-02 11:10:00');
insert into action values(6,'浏览','2020-01-02 11:50:00');
insert into action values(6,'点击','2020-01-02 12:00:00');
insert into action values(6,'下单','2020-01-02 12:10:00');
~~~
以30分钟作为一个时间窗口,返回满足在指定滑动窗口内的连续触发条件的最大值。
~~~SQL
SELECT
user_id,
windowFunnel(1800)(time, event_type = '浏览', event_type = '点击', event_type = '下单', event_type = '支付') AS level
FROM
(
SELECT
time,
event_type,
uid AS user_id
FROM action
)
GROUP BY user_id
~~~
- ClickHouse
- 第一节 ClickHouse入门
- 1.1 ClickHouse概述
- 1.2 ClickHouse单机安装
- 1.3 ClickHouse配置
- 1.4 ClickHouse数据库引擎
- 1.5 ClickHouse集群部署
- 第二节 ClickHouse进阶
- 2.1 ClicKHouse数据类型
- 2.2 ClicKHouse基本语法
- 2.3 ClickHouse引擎
- 2.4 ClickHouse函数
- 2.5 ClickHouse分布式表
- 2.6 ClickHouse权限和密码加密
- 2.7 ClickHouse数据导入和导出
- 第三节 ClicKHouse实战篇
- 3.1 ClickHouse的JDBC连接
- 3.2 ClickHouse用户行为分析
- 3.3 ClickHouse实战
- 第四节 ClicKHouse常见问题
- 4.1 ClickHouse常见问题汇总
- 第五节 ClickHouse其他
- 5.1 ClickHouse可视化工具
- 5.2 ClickHouse学习教程