- 类别:
HASH¶
返回已签名的 64 位哈希值。请注意,HASH 从不返回 NULL,即使对于 NULL 输入也如此。
HASH 函数的可能用途包括:
将偏斜数据值转换为可能更随机分布或更均匀分布的值。
例如,您可以对一组高度偏斜的值进行哈希处理,并生成一组更可能随机分布或均匀分布的值。
将数据放入桶中。由于哈希可以将偏斜数据值转换为更可能均匀分布的值,因此您可以使用哈希来帮助获取偏斜值并创建大小大致均匀的桶。
如果仅哈希不足以获得所需的不同桶的数量,您可以将哈希与 ROUND 或 WIDTH_BUCKET 函数结合使用。
备注
HASH 是专有函数,接受可变数量的任意类型输入表达式,并返回已签名的值。它 不是 加密哈希函数,不应用作加密哈希函数。
加密哈希函数具有此函数所没有的一些属性,例如:
无法反转值的加密哈希以查找原始值。
给定一个值,无法找到具有相同加密哈希值的另一个值。
如需加密,请使用 SHA 系列函数(在 字符串和二进制函数 中)。
- 另请参阅:
语法¶
HASH( <expr> [ , <expr> ... ] )
HASH(*)
实参¶
expr
表达式可以是任何 Snowflake 数据类型的常规表达式。
*
根据每条记录(包括带 NULL 值的记录)中的所有列,返回一个哈希处理的值。
当您将通配符传递给函数时,您可以使用表的名称或别名来限定通配符。例如,要传入名为
mytable
的表中的所有列,请指定以下内容:(mytable.*)
您还可以使用 ILIKE 和 EXCLUDE 关键字进行筛选:
ILIKE 筛选条件,用于查找与指定模式匹配的列名。只允许使用一种模式。例如:
(* ILIKE 'col1%')
EXCLUDE 筛选出与指定列或列不匹配的列名。例如:
(* EXCLUDE col1) (* EXCLUDE (col1, col2))
使用这些关键字时,限定符有效。以下示例使用 ILIKE 关键字筛选出与表
mytable
中的模式col1%
相匹配的所有列:(mytable.* ILIKE 'col1%')
ILIKE 和 EXCLUDE 关键字不能组合在单个函数调用中。
对于此函数,ILIKE 和 EXCLUDE 关键字仅在 SELECT 列表或 GROUP BY 子句中有效。
关于 ILIKE 和 EXCLUDE 关键字的更多信息,请参阅 SELECT 中的“参数”部分。
返回¶
返回已签名的 64 位值 NUMBER (19,0)。
HASH 从不返回 NULL,即使对于 NULL 输入也是如此。
使用说明¶
HASH 从某种意义上说是 稳定的,因为它保证:
任何两个平等比较的类型 NUMBER 值都将哈希为相同的哈希值,即使各自的类型具有不同的精度和/或小数位数。
如果两个类型 FLOAT 值可以在不损失精度的情况下转换为 NUMBER (38, 0),这个值将哈希为相同的值。例如,以下所有内容都返回相同的哈希值:
HASH(10::NUMBER(38,0))
HASH(10::NUMBER(5,3))
HASH(10::FLOAT)
任何两个平等比较的类型 TIMESTAMP_TZ 值都将哈希为相同的哈希值,即使时间戳来自不同的时区。
此保证也适用于 VARIANT 列中的 NUMBER、FLOAT 和 TIMESTAMP_TZ 值。
请注意,此保证 不 适用于其他类型组合,即使类型之间存在隐式转换也是如此。例如,即使在隐式转换后
10 = '10'
,以下内容也不太可能返回相同的哈希值:HASH(10)
HASH('10')
HASH(*)
表示基于行中的所有列创建单个哈希值。不要使用 HASH 创建唯一键。HASH 具有 64 位的有限分辨率,如果输入的值超过 2^64 个(例如,对于超过 2^64 行的表),则肯定返回非唯一值。实际上,如果输入大约为 2^32 行(约 40 亿行)或更多,则该函数很可能返回至少一个重复值。
排序规则详细信息¶
No impact.
如果两个字符串实际相同,但具有不同的排序规则规范,则它们具有相同的哈希值。换句话说,只有字符串(而不是排序规则规范)会影响哈希值。
如果根据排序规则,两个字符串实际不同,但在比较时却被视为相等,则它们可能具有不同的哈希值。例如,使用不区分标点符号的排序规则的两个相同字符串通常具有不同的哈希值,因为只有字符串(而不是排序规则规范)会影响哈希值。
示例¶
SELECT HASH(SEQ8()) FROM TABLE(GENERATOR(rowCount=>10));
+----------------------+
| HASH(SEQ8()) |
|----------------------|
| -6076851061503311999 |
| -4730168494964875235 |
| -3690131753453205264 |
| -7287585996956442977 |
| -1285360004004520191 |
| 4801857165282451853 |
| -2112898194861233169 |
| 1885958945512144850 |
| -3994946021335987898 |
| -3559031545629922466 |
+----------------------+
SELECT HASH(10), HASH(10::number(38,0)), HASH(10::number(5,3)), HASH(10::float);
+---------------------+------------------------+-----------------------+---------------------+
| HASH(10) | HASH(10::NUMBER(38,0)) | HASH(10::NUMBER(5,3)) | HASH(10::FLOAT) |
|---------------------+------------------------+-----------------------+---------------------|
| 1599627706822963068 | 1599627706822963068 | 1599627706822963068 | 1599627706822963068 |
+---------------------+------------------------+-----------------------+---------------------+
SELECT HASH(10), HASH('10');
+---------------------+---------------------+
| HASH(10) | HASH('10') |
|---------------------+---------------------|
| 1599627706822963068 | 3622494980440108984 |
+---------------------+---------------------+
SELECT HASH(null), HASH(null, null), HASH(null, null, null);
+---------------------+--------------------+------------------------+
| HASH(NULL) | HASH(NULL, NULL) | HASH(NULL, NULL, NULL) |
|---------------------+--------------------+------------------------|
| 8817975702393619368 | 953963258351104160 | 2941948363845684412 |
+---------------------+--------------------+------------------------+
下面的示例表明,即使表包含多列,HASH(*)
也为每行返回单个值。
CREATE TABLE orders (order_ID INTEGER, customer_ID INTEGER, order_date ...);
...
SELECT HASH(*) FROM orders LIMIT 10;
+-----------------------+
| HASH(*) |
|-----------------------|
| -3527903796973745449 |
| 6296330861892871310 |
| 6918165900200317484 |
| -2762842444336053314 |
| -2340602249668223387 |
| 5248970923485160358 |
| -5807737826218607124 |
| 428973568495579456 |
| 2583438210124219420 |
| 4041917286051184231 |
+ ----------------------+