编码函数
char
返回长度为传递参数数量的字符串,每个字节的值为对应参数的值。接受多个数值类型参数。如果参数值超出 UInt8 数据类型的范围,则将其转换为 UInt8,可能会进行舍入和溢出。
语法
char(number_1, [number_2, ..., number_n]);
参数
返回值
- 给定字节的字符串。 String。
示例
查询
SELECT char(104.1, 101, 108.9, 108.9, 111) AS hello;
结果
┌─hello─┐
│ hello │
└───────┘
您可以通过传递相应的字节来构造任意编码的字符串。以下是 UTF-8 的示例
查询
SELECT char(0xD0, 0xBF, 0xD1, 0x80, 0xD0, 0xB8, 0xD0, 0xB2, 0xD0, 0xB5, 0xD1, 0x82) AS hello;
结果
┌─hello──┐
│ привет │
└────────┘
查询
SELECT char(0xE4, 0xBD, 0xA0, 0xE5, 0xA5, 0xBD) AS hello;
结果
┌─hello─┐
│ 你好 │
└───────┘
hex
返回包含参数十六进制表示形式的字符串。
别名:HEX
。
语法
hex(arg)
该函数使用大写字母 A-F
,并且不使用任何前缀(如 0x
)或后缀(如 h
)。
对于整数参数,它会从最高有效位到最低有效位打印十六进制数字(“nibbles”)(大端序或“人类可读”顺序)。它从最高有效非零字节开始(忽略前导零字节),但始终打印每个字节的两位数字,即使前导数字为零。
类型为 Date 和 DateTime 的值将格式化为相应的整数(对于 Date 而言是从纪元开始的天数,对于 DateTime 而言是 Unix 时间戳的值)。
对于 String 和 FixedString,所有字节都简单地编码为两个十六进制数字。零字节不会被省略。
类型为 Float 和 Decimal 的值将编码为其在内存中的表示形式。由于我们支持小端序架构,因此它们以小端序编码。不会省略前导/尾随零字节。
类型为 UUID 的值将编码为大端序字符串。
参数
返回值
- 包含参数十六进制表示形式的字符串。 String。
示例
查询
SELECT hex(1);
结果
01
查询
SELECT hex(toFloat32(number)) AS hex_presentation FROM numbers(15, 2);
结果
┌─hex_presentation─┐
│ 00007041 │
│ 00008041 │
└──────────────────┘
查询
SELECT hex(toFloat64(number)) AS hex_presentation FROM numbers(15, 2);
结果
┌─hex_presentation─┐
│ 0000000000002E40 │
│ 0000000000003040 │
└──────────────────┘
查询
SELECT lower(hex(toUUID('61f0c404-5cb3-11e7-907b-a6006ad3dba0'))) as uuid_hex
结果
┌─uuid_hex─────────────────────────┐
│ 61f0c4045cb311e7907ba6006ad3dba0 │
└──────────────────────────────────┘
unhex
执行 hex 的相反操作。它将每个十六进制数字对(在参数中)解释为一个数字,并将其转换为该数字表示的字节。返回值为二进制字符串 (BLOB)。
如果要将结果转换为数字,可以使用 reverse 和 reinterpretAs<Type> 函数。
如果从 clickhouse-client
中调用 unhex
,则二进制字符串将使用 UTF-8 显示。
别名:UNHEX
。
语法
unhex(arg)
参数
arg
— 包含任意数量十六进制数字的字符串。 String,FixedString。
支持大写和小写字母 A-F
。十六进制数字的数量不必为偶数。如果为奇数,则最后一个数字将解释为 00-0F
字节的最低有效一半。如果参数字符串包含十六进制数字以外的任何内容,则将返回一些实现定义的结果(不会抛出异常)。对于数值参数,hex(N) 的反函数不会由 unhex() 执行。
返回值
- 二进制字符串 (BLOB)。 String。
示例
查询
SELECT unhex('303132'), UNHEX('4D7953514C');
结果
┌─unhex('303132')─┬─unhex('4D7953514C')─┐
│ 012 │ MySQL │
└─────────────────┴─────────────────────┘
查询
SELECT reinterpretAsUInt64(reverse(unhex('FFF'))) AS num;
结果
┌──num─┐
│ 4095 │
└──────┘
bin
返回包含参数二进制表示形式的字符串。
语法
bin(arg)
别名:BIN
。
对于整数参数,它会从最高有效位到最低有效位打印二进制数字(大端序或“人类可读”顺序)。它从最高有效非零字节开始(忽略前导零字节),但始终打印每个字节的八位数字,即使前导数字为零。
类型为 Date 和 DateTime 的值将格式化为相应的整数(对于 Date
而言是从纪元开始的天数,对于 DateTime
而言是 Unix 时间戳的值)。
对于 String 和 FixedString,所有字节都简单地编码为八个二进制数字。零字节不会被省略。
类型为 Float 和 Decimal 的值将编码为其在内存中的表示形式。由于我们支持小端序架构,因此它们以小端序编码。不会省略前导/尾随零字节。
类型为 UUID 的值将编码为大端序字符串。
参数
返回值
- 包含参数二进制表示形式的字符串。 String。
示例
查询
SELECT bin(14);
结果
┌─bin(14)──┐
│ 00001110 │
└──────────┘
查询
SELECT bin(toFloat32(number)) AS bin_presentation FROM numbers(15, 2);
结果
┌─bin_presentation─────────────────┐
│ 00000000000000000111000001000001 │
│ 00000000000000001000000001000001 │
└──────────────────────────────────┘
查询
SELECT bin(toFloat64(number)) AS bin_presentation FROM numbers(15, 2);
结果
┌─bin_presentation─────────────────────────────────────────────────┐
│ 0000000000000000000000000000000000000000000000000010111001000000 │
│ 0000000000000000000000000000000000000000000000000011000001000000 │
└──────────────────────────────────────────────────────────────────┘
查询
SELECT bin(toUUID('61f0c404-5cb3-11e7-907b-a6006ad3dba0')) as bin_uuid
结果
┌─bin_uuid─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 01100001111100001100010000000100010111001011001100010001111001111001000001111011101001100000000001101010110100111101101110100000 │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
unbin
将每个二进制数字对(在参数中)解释为一个数字,并将其转换为该数字表示的字节。该函数执行 bin 的相反操作。
语法
unbin(arg)
别名:UNBIN
。
对于数值参数 unbin()
不会返回 bin()
的反函数。如果要将结果转换为数字,可以使用 reverse 和 reinterpretAs<Type> 函数。
如果从 clickhouse-client
中调用 unbin
,则二进制字符串将使用 UTF-8 显示。
支持二进制数字 0
和 1
。二进制数字的数量不必是 8 的倍数。如果参数字符串包含二进制数字以外的任何内容,则将返回一些实现定义的结果(不会抛出异常)。
参数
arg
— 包含任意数量二进制数字的字符串。 String。
返回值
- 二进制字符串 (BLOB)。 String。
示例
查询
SELECT UNBIN('001100000011000100110010'), UNBIN('0100110101111001010100110101000101001100');
结果
┌─unbin('001100000011000100110010')─┬─unbin('0100110101111001010100110101000101001100')─┐
│ 012 │ MySQL │
└───────────────────────────────────┴───────────────────────────────────────────────────┘
查询
SELECT reinterpretAsUInt64(reverse(unbin('1110'))) AS num;
结果
┌─num─┐
│ 14 │
└─────┘
bitmaskToList(num)
接受一个整数。返回一个包含 2 的幂的列表的字符串,这些幂的和等于源数字。它们以文本格式以逗号分隔,中间没有空格,并按升序排列。
bitmaskToArray(num)
接受一个整数。返回一个包含 UInt64 数字的数组,这些数字包含 2 的幂的列表,这些幂的和等于源数字。数组中的数字按升序排列。
bitPositionsToArray(num)
接受一个整数并将其转换为无符号整数。返回一个包含 UInt64
数字的数组,这些数字包含 arg
中等于 1
的位的位的列表,并按升序排列。
语法
bitPositionsToArray(arg)
参数
arg
— 整数值。 Int/UInt。
返回值
示例
查询
SELECT bitPositionsToArray(toInt8(1)) AS bit_positions;
结果
┌─bit_positions─┐
│ [0] │
└───────────────┘
查询
SELECT bitPositionsToArray(toInt8(-1)) AS bit_positions;
结果
┌─bit_positions─────┐
│ [0,1,2,3,4,5,6,7] │
└───────────────────┘
mortonEncode
计算一组无符号整数的 Morton 编码(Z 曲线)。
该函数有两种操作模式
- 简单模式
- 扩展模式
简单模式
最多接受 8 个无符号整数作为参数并生成一个 UInt64 代码。
语法
mortonEncode(args)
参数
args
: 最多 8 个 无符号整数 或上述类型的列。
返回值
- 一个 UInt64 代码。 UInt64
示例
查询
SELECT mortonEncode(1, 2, 3);
结果
53
扩展模式
接受一个范围掩码(元组)作为第一个参数,以及最多 8 个 无符号整数 作为其他参数。
掩码中的每个数字配置范围扩展量
1 - 无扩展
2 - 2 倍扩展
3 - 3 倍扩展
...
最多 8 倍扩展。
语法
mortonEncode(range_mask, args)
参数
range_mask
: 1-8.args
: 最多 8 个 无符号整数 或上述类型的列。
注意:当使用列作为 args
时,提供的 range_mask
元组仍应为常量。
返回值
- 一个 UInt64 代码。 UInt64
示例
当您需要为范围(或基数)差异很大的参数获得类似的分布时,范围扩展可能很有用。例如:“IP 地址”(0...FFFFFFFF)和“国家代码”(0...FF)。
查询
SELECT mortonEncode((1,2), 1024, 16);
结果
1572864
注意:元组大小必须等于其他参数的数量。
示例
一个参数的莫顿编码始终是参数本身。
查询
SELECT mortonEncode(1);
结果
1
示例
也可以扩展一个参数。
查询
SELECT mortonEncode(tuple(2), 128);
结果
32768
示例
您也可以在函数中使用列名。
查询
首先创建表并插入一些数据。
create table morton_numbers(
n1 UInt32,
n2 UInt32,
n3 UInt16,
n4 UInt16,
n5 UInt8,
n6 UInt8,
n7 UInt8,
n8 UInt8
)
Engine=MergeTree()
ORDER BY n1 SETTINGS index_granularity = 8192, index_granularity_bytes = '10Mi';
insert into morton_numbers (*) values(1,2,3,4,5,6,7,8);
使用列名代替常量作为函数参数传递给mortonEncode
。
查询
SELECT mortonEncode(n1, n2, n3, n4, n5, n6, n7, n8) FROM morton_numbers;
结果
2155374165
实现细节
请注意,您只能将有限数量的信息放入莫顿代码中,因为UInt64 的限制。两个参数的范围最大为 2^32(64/2),三个参数的范围最大为 2^21(64/3),依此类推。所有溢出都将被截断为零。
mortonDecode
将莫顿编码(Z 曲线)解码为相应的无符号整数元组。
与mortonEncode
函数一样,此函数也有两种操作模式。
- 简单模式
- 扩展模式
简单模式
将结果元组大小作为第一个参数,并将代码作为第二个参数。
语法
mortonDecode(tuple_size, code)
参数
tuple_size
:整数,不超过 8。code
:UInt64 代码。
返回值
示例
查询
SELECT mortonDecode(3, 53);
结果
["1","2","3"]
扩展模式
将范围掩码(元组)作为第一个参数,并将代码作为第二个参数。掩码中的每个数字都配置范围缩小的量。
1 - 不缩小
2 - 2 倍缩小
3 - 3 倍缩小
...
最多 8 倍缩小。
当您需要为范围(或基数)差异很大的参数获得类似的分布时,范围扩展可能很有用。例如:“IP 地址”(0...FFFFFFFF)和“国家代码”(0...FF)。与编码函数一样,这也最多限于 8 个数字。
示例
查询
SELECT mortonDecode(1, 1);
结果
["1"]
示例
也可以缩小一个参数。
查询
SELECT mortonDecode(tuple(2), 32768);
结果
["128"]
示例
您也可以在函数中使用列名。
首先创建表并插入一些数据。
查询
create table morton_numbers(
n1 UInt32,
n2 UInt32,
n3 UInt16,
n4 UInt16,
n5 UInt8,
n6 UInt8,
n7 UInt8,
n8 UInt8
)
Engine=MergeTree()
ORDER BY n1 SETTINGS index_granularity = 8192, index_granularity_bytes = '10Mi';
insert into morton_numbers (*) values(1,2,3,4,5,6,7,8);
使用列名代替常量作为函数参数传递给mortonDecode
。
查询
select untuple(mortonDecode(8, mortonEncode(n1, n2, n3, n4, n5, n6, n7, n8))) from morton_numbers;
结果
1 2 3 4 5 6 7 8
hilbertEncode
计算希尔伯特曲线的一系列无符号整数的代码。
该函数有两种操作模式
- 简单模式
- 扩展模式
简单模式
简单模式:最多接受两个无符号整数作为参数,并生成一个 UInt64 代码。
语法
hilbertEncode(args)
参数
args
:最多 2 个无符号整数 或上述类型的列。
返回值
- 一个 UInt64 代码。
类型:UInt64
示例
查询
SELECT hilbertEncode(3, 4);
结果
31
扩展模式
将范围掩码(元组)作为第一个参数,并最多接受两个无符号整数 作为其他参数。
掩码中的每个数字都配置相应参数将左移的位数,从而有效地缩放其范围内的参数。
语法
hilbertEncode(range_mask, args)
参数
注意:当使用列作为 args
时,提供的 range_mask
元组仍应为常量。
返回值
- 一个 UInt64 代码。
类型:UInt64
示例
当您需要为范围(或基数)差异很大的参数获得类似的分布时,范围扩展可能很有用。例如:“IP 地址”(0...FFFFFFFF)和“国家代码”(0...FF)。
查询
SELECT hilbertEncode((10,6), 1024, 16);
结果
4031541586602
注意:元组大小必须等于其他参数的数量。
示例
对于没有元组的单个参数,函数将参数本身作为希尔伯特索引返回,因为不需要进行维度映射。
查询
SELECT hilbertEncode(1);
结果
1
示例
如果为单个参数提供了指定位移的元组,则函数会将该参数左移指定位数。
查询
SELECT hilbertEncode(tuple(2), 128);
结果
512
示例
该函数还接受列作为参数。
查询
首先创建表并插入一些数据。
create table hilbert_numbers(
n1 UInt32,
n2 UInt32
)
Engine=MergeTree()
ORDER BY n1 SETTINGS index_granularity = 8192, index_granularity_bytes = '10Mi';
insert into hilbert_numbers (*) values(1,2);
使用列名代替常量作为函数参数传递给hilbertEncode
。
查询
SELECT hilbertEncode(n1, n2) FROM hilbert_numbers;
结果
13
实现细节
请注意,您只能将有限数量的信息放入希尔伯特代码中,因为UInt64 的限制。两个参数的范围最大为 2^32(64/2)。所有溢出都将被截断为零。
hilbertDecode
将希尔伯特曲线索引解码回无符号整数元组,表示多维空间中的坐标。
与hilbertEncode
函数一样,此函数也有两种操作模式。
- 简单模式
- 扩展模式
简单模式
最多接受两个无符号整数作为参数,并生成一个 UInt64 代码。
语法
hilbertDecode(tuple_size, code)
参数
tuple_size
:整数,不超过 2。code
:UInt64 代码。
返回值
- 指定大小的元组。
类型:UInt64
示例
查询
SELECT hilbertDecode(2, 31);
结果
["3", "4"]
扩展模式
将范围掩码(元组)作为第一个参数,并最多接受两个无符号整数作为其他参数。掩码中的每个数字都配置相应参数将左移的位数,从而有效地缩放其范围内的参数。
当您需要为范围(或基数)差异很大的参数获得类似的分布时,范围扩展可能很有用。例如:“IP 地址”(0...FFFFFFFF)和“国家代码”(0...FF)。与编码函数一样,这也最多限于 8 个数字。
示例
一个参数的希尔伯特代码始终是参数本身(作为元组)。
查询
SELECT hilbertDecode(1, 1);
结果
["1"]
示例
指定位移的单个参数将相应地右移。
查询
SELECT hilbertDecode(tuple(2), 32768);
结果
["128"]
示例
该函数接受代码列作为第二个参数。
首先创建表并插入一些数据。
查询
create table hilbert_numbers(
n1 UInt32,
n2 UInt32
)
Engine=MergeTree()
ORDER BY n1 SETTINGS index_granularity = 8192, index_granularity_bytes = '10Mi';
insert into hilbert_numbers (*) values(1,2);
使用列名代替常量作为函数参数传递给hilbertDecode
。
查询
select untuple(hilbertDecode(2, hilbertEncode(n1, n2))) from hilbert_numbers;
结果
1 2