1.
程序=数据结构 算法
——Nicklaus Wirth,图灵奖得主,Pascal之父
数据结构是数据存储组织的形式,是数据元素之间的关系表达。有了这些数据,我们需要计算这些数据——这就是算法。一般来说,特定的数据结构配备了特定的算法。解决计算机领域问题的方法是设计加上数据结构的算法。
在前一章中,我们的主题是 ClickHouse 基础数据类型和高级数据类型也介绍了这些数据类型的常见基础操作。本章介绍 ClickHouse 函数主题。
1.1.
众所周知,数据结构是数据元素相互关联的集合,描述了数据与数据之间的结构关系。数据元素之间的关联会产生不同的结构,如数组、队列、树木、图纸等。
1.1.1.
数据元素之间的关系 操作构成数据类型,抽象现有数据类型构成抽象数据类型(ADT),是包装值和操作的模型。这里的操作通常与功能、函数、方法等词背后的含义相同——都表达了数据计算和处理的过程。
抽象数据处理过程中最常见、最常的功能模块抽象成函数,放入函数库中,提供数据处理计算服务——是现代计算编程中最常见的 API——包装经常需要使用的代码,需要时可以直接调用——这是计算机编程中的函数。
函数Y= f(X) 。其中,入参集合X被称为f定义域,出参集合Y被称为f值域。
参考X和返回值Y的数据类型分别确定了函数的定义域和对应域(对应域不是值域,函数的值域是函数对应域的子集)。
定义域和对应域,加上函数名,形成函数签名。
1.1.2.
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 │
...
│ │
...
└────────────────────────────────┘
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 &nbs; │
│ 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 |