ClickHouse 函数极简教程

Posted 东海陈光剑

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ClickHouse 函数极简教程相关的知识,希望对你有一定的参考价值。


1. ClickHouse 函数

程序=数据结构+算法

——Nicklaus Wirth,图灵奖获得者,Pascal之父

“数据结构”是数据的存储组织形式,是数据元素之间的关系表达。有了这些“数据”之后,接下来就需要对这些数据进行计算处理——这就是“算法”。通常来说,特定的数据结构配备特定的算法。计算机领域的问题解决之道,就是设计合适的数据结构,加上合适的算法。

在前面的章节中,我们的主题是 ClickHouse 的基础数据类型和高级数据类型,同时,还介绍了这些数据类型的常用基础操作。本章介绍 ClickHouse 函数主题。

1.1. 概述

众所周知,数据结构,是相互之间存在关系的数据元素的集合,描述的是数据与数据之间的结构关系。数据元素之间关联,就会产生不同的结构,例如:数组、队列、树、图等结构。

1.1.1. ClickHouse函数简介

数据元素之间的“关系+操作”构成了数据类型,对已有的数据类型进行抽象就构成了抽象数据类型(ADT),就是封装了值和操作的模型。这里的“操作”,通常跟“功能”、“函数”、“方法”等词语背后表达的意义是同源的——都是表达了对数据的计算处理这个过程。

把数据处理过程中最普遍、最通用的功能模块抽象出来编写成“函数”,放到函数库中,提供数据处理计算服务——就是现代计算编程中最常见的 API —— 将一段经常需要使用的代码封装起来,在需要使用时可以直接调用——这就是计算机编程中的函数。

函数Y = f(X) 。其中,入参集合X被称为f的定义域,出参集合Y被称为f的值域。

入参X和返回值Y的数据类型,分别确定了该函数的定义域和对应域(对应域不是值域,函数的值域是函数的对应域的子集)。

定义域和对应域,加上函数名就组成了“函数签名”。

1.1.2. ClickHouse 函数分类

ClickHouse 中的函数有常规函数(regular functions)和聚合函数(aggregate function)两大类。常规函数的入参是每一行数据,对于每一行,函数的结果不依赖于其他行。聚合函数则是从不同的行,累积一组值(即它们依赖于整组行)进行聚合计算。另外,还有数组“炸裂”函数arrayJoin()、表函数等特殊功能的函数。

ClickHouse 中的函数可分为算术函数、数组操作函数、数组连接、位函数、位图函数、比较函数、条件函数、日期时间函数、编码函数、加密函数、扩展字典函数、文件操作函数、空值函数、哈希函数、IN 函数、自省函数(系统内部监控打点跟踪等功能)、IP地址函数、json函数、逻辑函数、机器学习函数、数学函数、NLP函数、随机函数、舍入函数、拆分合并函数、字符串函数、字符串替换函数、字符串搜索函数、时间窗口函数、元组函数、元组映射函数、类型转换函数、url函数、uuid函数、YM字典函数和其他函数等。

执行如下SQL:

SELECT *

FROM system.functions

ORDER BY name ASC

可以获取 ClickHouse 中的所有的函数 (常规函数+聚合函数)。

ClickHouse 函数清单见《附件1: ClickHouse 函数一览表》。

ClickHouse 有个内置的系统库system,我们可以去看一下系统库里面都有什么表。

USE system

SHOW TABLES

输出结果如下(从表名我们可以看出来这些表是做什么的):

┌─name───────────────────────────┐

│ aggregate_function_combinators │

   ......

│ databases                      │

   ......

functions                      │

     ......

└────────────────────────────────┘

66 rows in set. Elapsed: 0.014 sec.

1.1.3. 表级别函数

查看 ClickHouse 中有哪些表级别函数:

SELECT *

FROM table_functions

输出:

┌─name───────────────┐

│ dictionary         │

│ numbers_mt         │

│ view               │

│ cosn               │

│ generateRandom     │

│ remote             │

│ input              │

│ s3Cluster          │

│ values             │

│ s3                 │

│ url                │

│ remoteSecure       │

│ sqlite             │

│ zeros              │

│ jdbc               │

│ zeros_mt           │

│ postgresql         │

│ odbc               │

│ executable         │

│ clusterAllReplicas │

│ cluster            │

│ merge              │

│ null               │

│ file               │

│ numbers            │

└────────────────────┘

25 rows in set. Elapsed: 0.004 sec.

看一下 ClickHouse 都支持哪些表引擎:

SELECT name

FROM table_engines

输出:

┌─name───────────────────────────────────┐

│ PostgreSQL                             │

│ RabbitMQ                               │

│ Kafka                                  │

│ S3                                     │

│ ExecutablePool                         │

│ MaterializedView                       │

│ MaterializedPostgreSQL                 │

│ EmbeddedRocksDB                        │

│ View                                   │

│ JDBC                                   │

│ Join                                   │

│ ExternalDistributed                    │

│ Executable                             │

│ Set                                    │

│ Dictionary                             │

│ GenerateRandom                         │

│ LiveView                               │

│ MergeTree                              │

│ Memory                                 │

│ Buffer                                 │

│ MongoDB                                │

│ URL                                    │

│ ReplicatedVersionedCollapsingMergeTree │

│ ReplacingMergeTree                     │

│ ReplicatedSummingMergeTree             │

│ COSN                                   │

│ ReplicatedAggregatingMergeTree         │

│ ReplicatedCollapsingMergeTree          │

│ File                                   │

│ ReplicatedGraphiteMergeTree            │

│ ReplicatedMergeTree                    │

│ ReplicatedReplacingMergeTree           │

│ VersionedCollapsingMergeTree           │

│ SummingMergeTree                       │

│ Distributed                            │

│ TinyLog                                │

│ GraphiteMergeTree                      │

│ SQLite                                 │

│ CollapsingMergeTree                    │

│ Merge                                  │

│ AggregatingMergeTree                   │

│ ODBC                                   │

│ Null                                   │

│ StripeLog                              │

│ Log                                    │

└────────────────────────────────────────┘

45 rows in set. Elapsed: 0.010 sec.

1.1.4. 聚合函数算子

SELECT *

FROM aggregate_function_combinators

输出:

┌─name────────┬─is_internal─┐

│ SimpleState │           0 │

│ OrDefault   │           0 │

│ Distinct    │           0 │

│ Resample    │           0 │

│ ForEach     │           0 │

│ OrNull      │           0 │

│ Merge       │           0 │

│ State       │           0 │

│ Array       │           0 │

│ Null        │           1 │

│ Map         │           0 │

│ If          │           0 │

└─────────────┴─────────────┘

12 rows in set. Elapsed: 0.006 sec.

1.2. 算术运算函数

对于所有算术函数(arithmetic functions),会对计算结果根据根据位数、是否有符号以及是否浮动,最小值等条件进行类型推断,采用适合的最小数字类型。如果没有足够的位,则采用最高位类型。例如:

SELECT

    toTypeName(0),

    toTypeName(0 + 0),

    toTypeName((0 + 0) + 0),

    toTypeName(((0 + 0) + 0) + 0)

FORMAT Vertical

输出:

toTypeName(0):                            UInt8

toTypeName(plus(0, 0)):                   UInt16

toTypeName(plus(plus(0, 0), 0)):          UInt32

toTypeName(plus(plus(plus(0, 0), 0), 0)): UInt64

算术函数适用于 UInt8、UInt16、UInt32、UInt64、Int8、Int16、Int32、Int64、Float32 或 Float64 中的任何类型对。溢出的产生方式与 C++ 中的相同。ClickHouse 中算术运算函数一览表如下。

函数

功能说明

使用实例

plus(a, b), a + b

加法运算。还可以添加带有日期或日期和时间的整数。在日期的情况下,添加一个整数意味着添加相应的天数。对于带时间的日期,这意味着添加相应的秒数。

1.数字加法:

SELECT 1 + 1┌─plus(1, 1)─┐│          2 │└────────────┘

2.日期、时间加法

SELECT

    toDate('2022-03-11') + 1 AS d,

toDateTime('2022-03-11 18:42:14') + 10 AS t

┌──────────d─┬───────────────────t─┐

│ 2022-03-12 │ 2022-03-11 18:42:24 │

└────────────┴─────────────────────┘

minus(a, b), a - b

减法运算。结果总是有符号类型。跟加法类似,减法运算也可以从日期或日期与时间计算整数

1.数字减法

SELECT

    5 - 1 AS a,

    toTypeName(a) AS t

┌─a─┬─t─────┐

│ 4 │ Int16 │

└───┴───────┘

2.日期、时间减法

SELECT

    toDate('2022-03-11') - 1 AS d,

    toDateTime('2022-03-11 18:42:14') - 10 AS t

┌──────────d─┬───────────────────t─┐

│ 2022-03-10 │ 2022-03-11 18:42:04 │

└────────────┴─────────────────────┘

multiply(a, b), a * b

乘法运算。

SELECT 8 * 8┌─multiply(8, 8)─┐│             64 │└────────────────┘

divide(a, b), a / b

除法运算。结果类型始终为浮点类型。它不是整数除法。对于整数除法,请使用“intDiv”函数。除以零时,您会得到“inf”、“-inf”或“nan”。

SELECT

    1 / 0 AS a,

    0 / 0 AS b,

    8 / 4 AS c,

    toTypeName(a),

    toTypeName(b),

    toTypeName(c)

FORMAT Vertical

Row 1:

──────

a:                        inf

b:                        nan

c:                        2

toTypeName(divide(1, 0)): Float64

toTypeName(divide(0, 0)): Float64

toTypeName(divide(8, 4)): Float64

intDiv(a, b)

整数除法。结果按绝对值向下舍入。除以 0 会报错。

1.整数除法

SELECT    intDiv(7, 3) AS a,    7 / 3 AS b┌─a─┬──────────────────b─┐│ 2 │ 2.3333333333333335 │└───┴────────────────────┘

2.除以 0 报错

SELECT intDiv(1, 0)

Received exception from server (version 21.12.1):

Code: 153. DB::Exception: Received from localhost:9000. DB::Exception: Division by zero: While processing intDiv(1, 0). (ILLEGAL_DIVISION)

intDivOrZero(a, b)

与“intDiv”的不同之处在于它在除以0时返回0。

SELECT    intDivOrZero(1, 0) AS a,    intDivOrZero(1, 2) AS b,    intDivOrZero(5, 3) AS c┌─a─┬─b─┬─c─┐│ 0 │ 0 │ 1 │└───┴───┴───┘

modulo(a, b), a % b

取余运算。b 如果是 0,报错。

SELECT

    7.7 % 3 AS a,

    7 % 3 AS b,

    toTypeName(a),

    toTypeName(b)

FORMAT Vertical

Row 1:

──────

a:                          1.7000000000000002

b:                          1

toTypeName(modulo(7.7, 3)): Float64

toTypeName(modulo(7, 3)):   UInt8

moduloOrZero(a, b)

取余运算。b 如果是 0,返回 0。

SELECT    moduloOrZero(1, 0) AS a,    moduloOrZero(7, 3) AS b┌─a─┬─b─┐│ 0 │ 1 │└───┴───┘

negate(a), -a

取负数。

SELECT    1 AS a,    -a┌─a─┬─negate(1)─┐│ 1 │        -1 │└───┴───────────┘

abs(a)

取绝对值。

SELECT    -1 AS a,    abs(a) AS b┌──a─┬─b─┐│ -1 │ 1 │└────┴───┘

gcd(a, b)

求最大公约数。

SELECT gcd(12, 16) AS a┌─a─┐│ 4 │└───┘

lcm(a, b)

求最小公倍数。

SELECT lcm(12, 16) AS a┌──a─┐│ 48 │└────┘

max2(v1,v2)

求v1,v2 中大的数。

SELECT max2(1, 2)┌─max2(1, 2)─┐│          2 │└────────────┘

min2(v1,v2)

求v1,v2 中小的数。

SELECT min2(1, 2)┌─min2(1, 2)─┐│          1 │└────────────┘

1.3. 数组操作函数

ClickHouse中常用的数组操作函数一览表如下。

函数

功能说明

使用实例

empty(x)

检查输入数组是否为空。另外,empty()函数还可以判断字符串是否为空。

SELECT    empty([]) AS a,    empty([1]) AS b,    empty('') AS c┌─a─┬─b─┬─c─┐│ 1 │ 0 │ 1 │└───┴───┴───┘

notEmpty(x)

与empty(x)逻辑相反。

SELECT    notEmpty([]) AS a,    notEmpty([1]) AS b,    notEmpty('') AS c┌─a─┬─b─┬─c─┐│ 0 │ 1 │ 0 │└───┴───┴───┘

length(x)

返回数组元素个数(即数组长度)。结果类型为 UInt64。该函数也适用于字符串。

SELECT    '' AS a,    [] AS b,    [1] AS c,    length(a) AS len_a,    length(b) AS len_b,    length(c) AS len_cFORMAT VerticalQuery id: 80d439a6-ce84-4541-bd6c-5eebf5c537a8Row 1:──────a:     b:     []c:     [1]len_a: 0len_b: 0len_c: 1

range([start, ] end [, step])

构造数组。返回从 start 到 end - 1 的 UInt 数字数组,可以定制步长 step (默认为 1)。

SELECT    range(10) AS a,    range(1, 10) AS b,    range(1, 10, 2) AS cFORMAT VerticalQuery id: bbc61a37-648f-4e98-bf38-b2c41808bbf6Row 1:──────a: [0,1,2,3,4,5,6,7,8,9]b: [1,2,3,4,5,6,7,8,9]c: [1,3,5,7,9]

array(x1, ...)等价算子:[x1, ...]

从参数x1, ...创建一个数组。

SELECT    1 AS a,    2 AS b,    3 AS c,    [a, b, c],    [a, b, c]FORMAT VerticalQuery id: 8028676b-50c5-4ee4-8720-9ccebb1f1ee7Row 1:──────a:              1b:              2c:              3array(1, 2, 3): [1,2,3]array(1, 2, 3): [1,2,3]

arrayConcat(arrays)

把多个数组拼接成一个数组。

SELECT arrayConcat([1, 2], [3, 4], [5, 6]) AS resQuery id: 0e6b86af-8efb-43b4-b904-8bfb3f62786a┌─res───────────┐│ [1,2,3,4,5,6] │└───────────────┘1 rows in set. Elapsed: 0.001 sec.

arrayElement(arr, n)等价算子:arr[n]

获取数组 arr 中下标为 n 的元素。第 1 个元素的下标为 1。

SELECT    [1, 2, 3, 4, 5] AS arr,    arr[1] AS a1,    arr[2] AS a2FORMAT VerticalQuery id: d34fb174-49c9-41bd-993a-123cab8f4fc8Row 1:──────arr: [1,2,3,4,5]a1:  1a2:  2

has(arr, x)

判断数组 arr 是否包含元素 x。如果包含,返回 1;不包含返回 0。

SELECT    [1, 2, 3, 4, 5] AS arr,    3 AS x,    has(arr, x) AS resFORMAT VerticalQuery id: 6226fbba-fcba-449d-bb30-d281dd29f8a6Row 1:──────arr: [1,2,3,4,5]x:   3res: 1

hasAll(set, subset)

判断subset 是否是 set 的子数组。如果是,返回 1;不是,则返回 0。

SELECT    [1, 2, 3, 4, 5] AS set,    [1, 3] AS subset,    hasAll(set, subset) AS resFORMAT VerticalQuery id: d550e8d7-08f3-429d-aa62-44044b90d3efRow 1:──────set:    [1,2,3,4,5]subset: [1,3]res:    1

hasAny(array1, array2)

检查两个数组是否有任意元素的交集。有交集返回 1,无交集返回 0。

SELECT    [1, 2, 3, 4, 5] AS set,    [1, 3] AS subset,    [8, 9] AS y,    hasAny(set, subset) AS res1,    hasAny(set, y) AS res2FORMAT VerticalQuery id: 5a719a60-a247-479c-9876-044e4246a5beRow 1:──────set:    [1,2,3,4,5]subset: [1,3]y:      [8,9]res1:   1res2:   0

indexOf(arr, x)

返回第一个“x”元素在数组 arr 中的索引下标(从 1 开始),如果不存在,则返回 0。

SELECT    [1, 2, 3, 4, 5] AS arr,    3 AS x,    indexOf(arr, x) AS resFORMAT VerticalQuery id: cca82f39-ee51-4cd8-92e0-8ca792def342Row 1:──────arr: [1,2,3,4,5]x:   3res: 3

arraySlice(array, offset[, length])

返回数组的一个切片。- array - 目标数组。- offset -开始偏移量。正值表示左侧偏移,负值表示右侧。数组下标从 1 开始。- length - 所需切片的长度。

SELECT arraySlice([1, 2, 3, 4, 5], 2, 3) AS resQuery id: 8f50e22b-7fe0-46a5-8fb0-8102db0de1b3┌─res─────┐│ [2,3,4] │└─────────┘

arraySort(arr)

数组排序,默认升序(ascending order)。

SELECT arraySort([1, 3, 2, 5, 7, 6, 0])Query id: ff99177d-f59c-4163-84b1-2eaa82a26b5f┌─arraySort([1, 3, 2, 5, 7, 6, 0])─┐│ [0,1,2,3,5,6,7]                  │└──────────────────────────────────┘

arraySort(func, arr)

高阶函数。根据 func 函数(lambda)规则对数组 arr 进行排序。

SELECT arraySort(x -> (-x), [1, 2, 3]) AS resQuery id: a12359ca-6a2c-4efc-a606-7cd415c8e985┌─res─────┐│ [3,2,1] │└─────────┘

arrayReverseSort(arr)

数组降序排序(descending order)。

SELECT arrayReverseSort([1, 3, 3, 5, 7, 0])Query id: eaf0b594-29a9-481e-8bea-4e408dc31333┌─arrayReverseSort([1, 3, 3, 5, 7, 0])─┐│ [7,5,3,3,1,0]                        │└──────────────────────────────────────┘

arrayReverseSort(func,arr)

根据 func函数规则,对数组arr逆序排序(descending order)。

SELECT arrayReverseSort(x -> (-x), [1, 2, 3]) AS resQuery id: b992c3dd-25d7-4d46-a71c-ac467035128f┌─res─────┐│ [1,2,3] │└─────────┘

arrayUniq(arr)

计算数组 arr 中不重复元素个数。

SELECT arrayUniq([1, 2, 2, 3, 4, 5, 5, 6, 6, 6]) AS resQuery id: c3b5ea50-38b0-4b2a-ae22-4518985cf46a┌─res─┐│   6 │└─────┘

arrayDistinct(array)

数组去重。

SELECT arrayDistinct([1, 2, 2, 3, 4, 5, 5, 6, 6, 6]) AS resQuery id: 3588ebd9-d408-4010-8c99-84054660bb58┌─res───────────┐│ [1,2,3,4,5,6] │└───────────────┘

arrayIntersect(arr1,arr2,...)

计算数组交集。入参可为多个数组,返回一个包含所有源数组中存在的元素的数组。

SELECT    arrayIntersect([1, 2], [3, 4], [2, 3]) AS no_intersect,    arrayIntersect([1, 2, 5], [1, 2, 3], [1, 2, 4]) AS intersectQuery id: 08d3bec1-248f-4006-b620-f9e70765e60e┌─no_intersect─┬─intersect─┐│ []           │ [2,1]     │└──────────────┴───────────┘

arrayReduce(agg_func, arr1, arr2, ..., arrN)

将聚合函数应用于数组元素并返回其结果。聚合函数的名称以单引号 'max'、'sum' 中的字符串形式传递。使用参数聚合函数时,参数在括号中的函数名称后指示 'uniqUpTo(6)'。

SELECT arrayReduce('uniq', [1, 2, 3, 4, 5, 5, 5, 6, 6])Query id: 5072b860-c5ed-4328-8447-323253a35597┌─arrayReduce('uniq', [1, 2, 3, 4, 5, 5, 5, 6, 6])─┐│                                                6 │└──────────────────────────────────────────────────┘

arrayReverse(arr)

数组逆序。

SELECT arrayReverse([1, 2, 3])Query id: e37b8751-e81e-4a94-8444-5764935e5240┌─arrayReverse([1, 2, 3])─┐│ [3,2,1]                 │└─────────────────────────┘

flatten(arr1,arr2,...)

数组拍平。

SELECT flatten([[[1, 2, 3]], [[2, 3, 4], [3, 4, 5]]]) AS resQuery id: 6fde8afe-b038-43e6-b6f7-fe107f3a096d┌─res─────────────────┐│ [1,2,3,2,3,4,3,4,5] │└─────────────────────┘

arrayZip(arr1, arr2, ..., arrN)

将多个数组,合成一个元组数组。

SELECT arrayZip(['a', 'b', 'c'], [3, 2, 1])Query id: b4685efd-9179-42cc-89f8-6179cb0daa61┌─arrayZip(['a', 'b', 'c'], [3, 2, 1])─┐│ [('a',3),('b',2),('c',1)]            │└──────────────────────────────────────┘

arrayMap(func, arr, ...)

将 arr 数组中的每个元素应用 func 函数映射规则,返回新的数组。

SELECT arrayMap(x -> (x * x), [1, 2, 3]) AS resQuery id: d041bf8f-05f9-4c48-9a99-6fbbfeb509be┌─res─────┐│ [1,4,9] │└─────────┘SELECT arrayMap((x, y) -> (x * x, y * y), [1, 2, 3], [4, 5, 6]) AS resQuery id: 1553c910-8ffa-4162-af60-1ccc5e47da82┌─res────────────────────┐│ [(1,16),(4,25),(9,36)] │└────────────────────────┘

arrayFilter(func, arr1, …)

根据函数 func 规则过滤数组中的元素。

SELECT    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] AS arr,    arrayFilter(x -> ((x % 2) = 0), arr) AS resFORMAT VerticalQuery id: d8c6564d-1845-4403-bff5-e1cb5b19ad04Row 1:──────arr: [1,2,3,4,5,6,7,8,9,10]res: [2,4,6,8,10]

arrayMin([func,] arr)

计算数组最小元素。如果指定 func,则按照 func 规则映射之后计算最小值。

SELECT arrayMin([1, 2, 4]) AS res;┌─res─┐│   1 │└─────┘SELECT arrayMin(x -> (-x), [1, 2, 4]) AS res;┌─res─┐│  -4 │└─────┘

arrayMax([func,] arr)

计算数组最大元素。如果指定 func,则按照 func 规则映射之后计算最大值。

SELECT arrayMax([1, 2, 4]) AS res;┌─res─┐│   4 │└─────┘SELECT arrayMax(x -> (-x), [1, 2, 4]) AS res;┌─res─┐│  -1 │└─────┘

arraySum([func,] arr)

返回源数组中元素的总和。如果指定了 func 函数,则返回此函数转换的元素的总和。

SELECT arraySum([2, 3]) AS res;┌─res─┐│   5 │└─────┘SELECT arraySum(x -> (x * x), [1, 2, 3]) AS res┌─res─┐│  14 │└─────┘

arrayAvg([func,] arr)

计算平均值。如果指定了函数 func,则按照 func 映射规则之后的元素值计算。

SELECT arrayAvg([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) AS resQuery id: d39dcead-1136-40a8-9854-ece4c7970e44┌─res─┐│ 5.5 │└─────┘SELECT arrayAvg(x -> (x * x), [2, 4]) AS resQuery id: fb25c538-270c-46c6-b6b6-312c87887238┌─res─┐│  10 │└─────┘

arrayProduct(arr)

元素相乘。

SELECT arrayProduct([1, 2, 3, 4, 5, 6]) AS resQuery id: 0070f0f8-92b0-4e70-a7a6-85eb5db36e2f┌─res─┐│ 720 │└─────┘

arrayJoin(arr)

数组“炸开”,列转行,类似 Hive 中的 explode() 函数。

SELECT

    arrayJoin([1, 2, 3]) AS e,

    'abc' AS a

Query id: bd63929f-3809-45a2-a7c9-7e98db6c20c7

┌─e─┬─a───┐

│ 1 │ abc │

│ 2 │ abc │

│ 3 │ abc │

└───┴─────┘

1.4. 字符串操作函数

字符串可以说是 SQL 中最常用的数据类型了。只要人能阅读能看到的数据,都可以用字符串来表示。ClickHouse 中提供了丰富的字符串处理函数,清单如下。

函数

功能说明

使用实例

empty(x)

字符串判空。空字符串返回“1”;非空字符串返回“0”。

SELECT    empty('') AS res1,    empty('a') AS res2Query id: 15a1071d-54c5-44b2-8af1-e2cb3eacfb94┌─res1─┬─res2─┐│    1 │    0 │└──────┴──────┘

notEmpty(x)

与上面的empty(x)逻辑相反。字符串非空判断。非空字符串返回“1”;空字符串返回“0”。

SELECT    notEmpty('') AS res1,    notEmpty('a') AS res2Query id: ed0c29bb-d268-42f2-a6a8-7a4f42aa4c27┌─res1─┬─res2─┐│    0 │    1 │└──────┴──────┘

length(x)

返回以字节为单位的字符串长度(不是字符个数)。结果类型为 UInt64。该函数也适用于数组。NULL 的长度是 NULL。

SELECT    length('') AS res1,    length('abc') AS res2,    length(NULL) AS res3Query id: bd54cfc9-0059-4b30-98f1-182d24bb08f1┌─res1─┬─res2─┬─res3─┐│    0 │    3 │ ᴺᵁᴸᴸ │└──────┴──────┴──────┘

leftPad('x', length[, 'pad_string'])

左补齐字符串。参数说明:x - 需要填充的字符串。String 类型。length - 结果字符串的长度。如果值小于输入字符串长度,则输入字符串按原样返回。UInt类型。pad_string - 填充输入字符串的字符串。可选。如果未指定,则输入字符串将填充空格。

SELECT leftPad('10', 7, '0')Query id: 5fa441cb-6c3c-473e-bbe9-d92b31610c8b┌─leftPad('10', 7, '0')─┐│ 0000010               │└───────────────────────┘

rightPadPad('x', length[, 'pad_string'])

类似地,有右补齐字符串。

SELECT rightPad('abc', 11, '*')Query id: 44982f4e-e0f7-412a-9074-459579547b06┌─rightPad('abc', 11, '*')─┐│ abc********              │└──────────────────────────┘

lower(x)

转小写。

SELECT    'aBcD' AS x,    lower(x) AS resQuery id: 700f6c28-881b-46ca-9fe0-d3e5bb836dc4┌─x────┬─res──┐│ aBcD │ abcd │└──────┴──────┘

upper(x)

转大写。

SELECT    'aBcD' AS x,    lower(x) AS lx,    upper(x) AS uxQuery id: 37cda845-f767-44fd-83ea-ee9b726236c0┌─x────┬─lx───┬─ux───┐│ aBcD │ abcd │ ABCD │└──────┴──────┴──────┘

repeat(s, n)

重复 n 次字符串 s。

SELECT repeat('abc', 3)Query id: a394b92b-41d5-48a4-bb67-a0f253be29df┌─repeat('abc', 3)─┐│ abcabcabc        │└──────────────────┘

concat(s1, s2, ...)

拼接字符串。

SELECT concat('Hello', ', ', 'World!') AS resQuery id: cce740c7-00a1-4535-ba74-bc8f5153652b┌─res───────────┐│ Hello, World! │└───────────────┘

substring(s, offset, length)

返回子串。offset 从 1 开始。

SELECT    'abcdefg' AS s,    substring(s, 1, 3) AS resQuery id: d2759ab9-24b9-4e4b-99cb-bfdd0471054a┌─s───────┬─res─┐│ abcdefg │ abc │└─────────┴─────┘

base64Encode(s)

将字符串 s 编码为 base64

SELECT base64Encode('1234567890')Query id: 1203b202-51d7-40ff-a42f-3b7ed5b0fbc4┌─base64Encode('1234567890')─┐│ MTIzNDU2Nzg5MA==           │└────────────────────────────┘

base64Decode(x)

从base64 编码字符串解码原始字符串。

SELECT base64Decode('MTIzNDU2Nzg5MA==') AS resQuery id: 77d82caa-45a3-4f10-9205-e690cd278e78┌─res────────┐│ 1234567890 │└────────────┘

startsWith(s, prefix)

判断字符串 s 是否以 prefix 开头。

SELECT startsWith('abc', 'a') AS resQuery id: dbd3f560-3857-4422-8cb4-da4c16475669┌─res─┐│   1 │└─────┘

endsWith(s, suffix)

判断字符串 s 是否以 suffix 结尾。

SELECT endsWith('abc', 'c') AS resQuery id: 0f6fd140-8d3b-4903-8636-6beee5bc8b0e┌─res─┐│   1 │└─────┘

trimBoth(input_string)

从字符串的两端删除所有连续出现的公共空白(ASCII 字符中的 32)。它不会删除其他类型的空白字符(制表符、不间断空格等)。

SELECT trimBoth('     a bc  ')Query id: 86861168-89d1-4b12-bdeb-c5640d4a33dc┌─trimBoth('     a bc  ')─┐│ a bc                    │└─────────────────────────┘

extractTextFromhtml(x)

从 HTML 中提取纯文本。

SELECT extractTextFromHTML(' <p> A text <i>with</i><b>tags</b>. <!-- comments --> </p> ') AS resQuery id: 4a2096e9-3e16-40c3-945d-d02a173cbf11┌─res────────────────┐│ A text with tags . │└────────────────────┘SELECT extractTextFromHTML(html) AS resFROM url('https://www.baidu.com/', RawBLOB, 'html String')FORMAT VerticalQuery id: 3a85242e-007f-4608-9f4c-82e71458eb2bRow 1:──────res: 百度一下,你就知道 新闻 hao123 地图 直播 视频 贴吧 学术 更多 ......

replaceOne(haystack, pattern, replacement)

字符串替换。只替换找到的满足匹配目标字符第一个匹配的字符。

SELECT replaceOne('abc**defg**', '*', '$') AS resQuery id: 5fa4c73e-1912-4b8a-a3ab-2cab2ea749a1┌─res─────────┐│ abc$*defg** │└─────────────┘

replaceAll(haystack, pattern, replacement)

字符串替换。全部替换满足匹配目标字符模式的字符。

SELECT replaceAll('abc**defg**', '*', '$') AS resQuery id: 86350017-f1b5-4575-80f3-588608a61360┌─res─────────┐│ abc$$defg$$ │└─────────────┘

replaceRegexpOne(haystack, pattern, replacement)

字符串替换。只替换找到的第一个满足正则匹配模式的字符。

SELECT replaceRegexpOne('abc123def09', '(\\\\d)', '$') AS resQuery id: 8269034b-dfc1-41de-a2c3-74bc9b629b99┌─res─────────┐│ abc$23def09 │└─────────────┘

replaceRegexpAll(haystack, pattern, replacement)

字符串替换。全部替换满足正则匹配模式的字符。

SELECT replaceRegexpAll('abc123def09', '(\\\\d)', '$') AS resQuery id: c6a71725-c81c-4b53-9921-01e351354bb4┌─res─────────┐│ abc$$$def$$ │└─────────────┘

position(haystack, needle[, start_pos])等价于locate(haystack, needle[, start_pos])

如果找到子字符串,则返回以字节为单位的起始位置(从 1 开始计数)。如果未找到子字符串, 返回 0。

SELECT position('1234567890', '7') AS resQuery id: 80b88f03-d49e-40f6-b2f5-e4352adaee80┌─res─┐│   7 │└─────┘

match(haystack, pattern)

字符串正则匹配。如果匹配则返回 1,如果不匹配则返回 0。正则表达式不能包含空字节。对于在字符串中搜索子字符串的模式,最好使用 LIKE 或“位置”,因为它们的工作速度更快。

SELECT match('abcccddd', '(^abc)') AS resQuery id: f912bd49-d01e-4caf-967e-4de7df38181f┌─res─┐│   1 │└─────┘

like(haystack, pattern)

检查字符串是否匹配简单的正则表达式。正则表达式可以包含元符号 % 和 _。% 表示任意数量的任意字节(包括零个字符)。_ 表示任何一个字节。使用反斜杠  \\ 转义元符号。

SELECT    'abc' LIKE 'a%' AS re1,    '12345' LIKE '__3__' AS res2Query id: f1c49f53-a27c-43c6-b298-246fc242a115┌─re1─┬─res2─┐│   1 │    1 │└─────┴──────┘

countMatches(haystack, pattern)

返回字符串 haystack 中模式 pattern 的正则表达式匹配数。

SELECT    countMatches('foobar.com', 'o+') AS res1,    countMatches('aaaa', 'aa') AS res2Query id: 151e1c67-4562-4711-a30a-f34d7e143469┌─res1─┬─res2─┐│    2 │    2 │└──────┴──────┘

1.5. 条件分支函数

程序的三大控制结构为:顺序结构、循环结构、分支结构(选择结构)。顺序结构的程序虽然能解决计算、输出等问题,但不能做判断再选择。对于要先做判断再选择的问题就要使用分支结构。在各大编程语言中,都有类似 if,case-when 的分支语句。在 ClickHouse 中则是用条件函数(Conditional Function)if()、multiIf() 来实现分支逻辑的选择。常用清单如下。

函数

功能说明

使用实例

if(cond, then, else)

单条件分支函数。参数说明:cond - 判断条件。类型为 UInt8、Nullable(UInt8) 或 NULL。then - 满足条件时,返回的表达式。else - 不满足条件时,返回的表达式。

SELECT    if(2 > 1, 1, 0) AS res1,    if(1 > 2, 1, 0) AS res2Query id: 51a72550-928d-4b51-b07b-f59a59ce1905┌─res1─┬─res2─┐│    1 │    0 │└──────┴──────┘

multiIf(cond_1, then_1, cond_2, then_2, ..., else)

多条件分支函数。

SELECT multiIf(2 > 10, 'c1', 1 > 2, 'c2', 2 > 1, 'c3', NULL) AS resQuery id: 248137af-179a-43fe-83df-c6493930b5af┌─res─┐│ c3  │└─────┘

NULL 值条件判断

条件判断中有 NULL 值的,结果仍然是 NULL。因此,针对类型为“Nullable”的字段,需要仔细检查查询条件。

SELECT    NULL < 1,    2 < NULL,    NULL < NULL,    NULL = NULLQuery id: 72059d3d-7e7e-45e6-8728-49752c932f56┌─less(NULL, 1)─┬─less(2, NULL)─┬─less(NULL, NULL)─┬─equals(NULL, NULL)─┐│ ᴺᵁᴸᴸ          │ ᴺᵁᴸᴸ          │ ᴺᵁᴸᴸ             │ ᴺᵁᴸᴸ               │└───────────────┴───────────────┴──────────────────┴────────────────────┘

1.6. 时间计算函数

在人类的问题清单中,时间是一个重要的变量因素。计算机是用来解决人类问题的,故几乎在所有的编程语言、软件系统中,都有需要处理日期和时间的场景。在 ClickHouse 中专门设计了日期和时间类型,并提供了处理日期和时间的函数。

所有用于处理日期和时间的函数,都可以接受第二个可选的时区参数。例如:Asia/Shanghai,在这种情况下,他们使用指定的时区而不是本地时区(默认时区)。清单如下。

函数

功能说明

使用实例

now()

计算当前时间。

SELECT now()Query id: 5f12bb7e-31ce-4190-aeeb-ed7ba7c1e7aa┌───────────────now()─┐│ 2022-03-15 18:18:58 │└─────────────────────┘

today()

计算今天日期,与 toDate(now()) 逻辑等价。

SELECT today()Query id: 3a5c132c-3a0c-475d-a59c-b5e692cb2c09┌────today()─┐│ 2022-03-15 │└────────────┘

yesterday()

计算昨天日期,与 today() - 1 逻辑等价。

SELECT yesterday()Query id: 5ec0a7fc-1843-42d0-ae3a-1a1c7901e51f┌─yesterday()─┐│  2022-03-15 │└─────────────┘

timeZone()

计算当前时区。

SELECT timeZone()Query id: c082e992-4678-4803-9c7d-2b69958bcd61┌─timeZone()────┐│ Asia/Shanghai │└───────────────┘

timeZoneOf(value)

计算 DateTime/DateTime64 时间对象 value  的时区名称。

SELECT timezoneOf(now())Query id: 288b5e11-d6a1-4ae1-a144-0510e6761da1┌─timezoneOf(now())─┐│ Asia/Shanghai     │└───────────────────┘

toTimezone(value, timezone)

将时间或日期和时间转换为指定的时区的时间。

SELECT    toDateTime('2022-03-15 00:00:00', 'UTC') AS time_utc,    toTypeName(time_utc) AS type_utc,    toTimeZone(time_utc, 'Asia/Shanghai') AS time_shanghaiFORMAT VerticalQuery id: 4f586c94-d555-4ecf-aff4-e60529016e95Row 1:──────time_utc:      2022-03-15 00:00:00type_utc:      DateTime('UTC')time_shanghai: 2022-03-15 08:00:00

toYear(x)

将日期或带时间的日期转换为包含 公元后年号 (AD) 的 UInt16 数字。

SELECT    now() AS x,    toYear(x) AS yQuery id: c6bc02da-890b-4834-a00e-12426c849c7a┌───────────────────x─┬────y─┐│ 2022-03-15 18:21:03 │ 2022 │└─────────────────────┴──────┘

toQuarter(x)

将日期或带时间的日期转换为包含季度数字的 UInt8 数字。

SELECT    now() AS x,    toQuarter(x) AS yQuery id: bf25ccff-20ca-4d4d-8a6e-a04ec96953ce┌───────────────────x─┬─y─┐│ 2022-03-15 18:41:35 │ 1 │└─────────────────────┴───┘

toMonth(x)

将日期或带时间的日期转换为包含月份编号 (1-12) 的 UInt8 数字。

SELECT    now() AS x,    toMonth(x) AS yQuery id: 8fd85e2e-e4e7-4720-a9c6-a1957184147b┌───────────────────x─┬─y─┐│ 2022-03-15 18:41:06 │ 3 │└─────────────────────┴───┘

toDayOfYear(x)

将日期或带时间的日期转换为 UInt16 数字,其中包含一年中的日期 (1-366)。

SELECT    now() AS x,    toDayOfYear(x) AS yQuery id: cb7852f4-450b-48a2-9e0c-59b59e3884a4┌───────────────────x─┬──y─┐│ 2022-03-15 18:39:22 │ 74 │└─────────────────────┴────┘

toDayOfMonth(x)

将日期或带时间的日期转换为 UInt8 数字,其中包含月份中的天数 (1-31)。

SELECT    now() AS x,    toDayOfMonth(x) AS yQuery id: fbc39c16-5e2c-494b-97f4-a438999300b5┌───────────────────x─┬──y─┐│ 2022-03-15 18:38:43 │ 15 │└─────────────────────┴────┘

toDayOfWeek(x)

将日期或带时间的日期转换为包含星期几的 UInt8 数字(星期一为 1,星期日为 7)。

SELECT    now() AS x,    toDayOfWeek(x) AS yQuery id: cfe6fbb1-db7a-42ec-a00a-f28a2e737da8┌───────────────────x─┬─y─┐│ 2022-03-15 18:38:07 │ 2 │└─────────────────────┴───┘

toHour(x)

将带时间的日期转换为包含 24 小时制小时数 (0-23) 的 UInt8 数字。

SELECT    now() AS x,    toHour(x) AS yQuery id: 7bd0e1e8-43df-445c-8a23-1bc36e79f155┌───────────────────x─┬──y─┐│ 2022-03-15 18:36:48 │ 18 │└─────────────────────┴────┘

toMinute(x)

将带时间的日期转换为小

以上是关于ClickHouse 函数极简教程的主要内容,如果未能解决你的问题,请参考以下文章

ClickHouse SQL 语法极简教程

ClickHouse 实战:ClickHouse 基础数据类型极简教程

ClickHouse 实战:ClickHouse 高级数据类型极简教程

ClickHouse SQL 极简教程ClickHouse SQL之数据操作语言 DML

ClickHouse SQL 极简教程SQL基础知识

ClickHouse SQL 极简教程ClickHouse SQL之数据定义语言 DDL

(c)2006-2024 SYSTEM All Rights Reserved IT常识