跳至主要内容

编码函数

char

返回长度为传递参数数量的字符串,每个字节的值为对应参数的值。接受多个数值类型参数。如果参数值超出 UInt8 数据类型的范围,则将其转换为 UInt8,可能会进行舍入和溢出。

语法

char(number_1, [number_2, ..., number_n]);

参数

  • number_1, number_2, ..., number_n — 解释为整数的数值参数。类型:IntFloat

返回值

  • 给定字节的字符串。 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”)(大端序或“人类可读”顺序)。它从最高有效非零字节开始(忽略前导零字节),但始终打印每个字节的两位数字,即使前导数字为零。

类型为 DateDateTime 的值将格式化为相应的整数(对于 Date 而言是从纪元开始的天数,对于 DateTime 而言是 Unix 时间戳的值)。

对于 StringFixedString,所有字节都简单地编码为两个十六进制数字。零字节不会被省略。

类型为 FloatDecimal 的值将编码为其在内存中的表示形式。由于我们支持小端序架构,因此它们以小端序编码。不会省略前导/尾随零字节。

类型为 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)。

如果要将结果转换为数字,可以使用 reversereinterpretAs<Type> 函数。

注意

如果从 clickhouse-client 中调用 unhex,则二进制字符串将使用 UTF-8 显示。

别名:UNHEX

语法

unhex(arg)

参数

支持大写和小写字母 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

对于整数参数,它会从最高有效位到最低有效位打印二进制数字(大端序或“人类可读”顺序)。它从最高有效非零字节开始(忽略前导零字节),但始终打印每个字节的八位数字,即使前导数字为零。

类型为 DateDateTime 的值将格式化为相应的整数(对于 Date 而言是从纪元开始的天数,对于 DateTime 而言是 Unix 时间戳的值)。

对于 StringFixedString,所有字节都简单地编码为八个二进制数字。零字节不会被省略。

类型为 FloatDecimal 的值将编码为其在内存中的表示形式。由于我们支持小端序架构,因此它们以小端序编码。不会省略前导/尾随零字节。

类型为 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() 的反函数。如果要将结果转换为数字,可以使用 reversereinterpretAs<Type> 函数。

注意

如果从 clickhouse-client 中调用 unbin,则二进制字符串将使用 UTF-8 显示。

支持二进制数字 01。二进制数字的数量不必是 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)

参数

返回值

  • 包含等于 1 的位的位的列表的数组,并按升序排列。 Array(UInt64).

示例

查询

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)

参数

返回值

  • 一个 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。
  • codeUInt64 代码。

返回值

示例

查询

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)

参数

返回值

  • 一个 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。
  • codeUInt64 代码。

返回值

类型: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