合规国际互联网加速 OSASE为企业客户提供高速稳定SD-WAN国际加速解决方案。 广告
## 高阶函数 高阶函数、`->`运算符和 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 ~~~