类别:

聚合函数窗口函数

HASH_AGG

返回输入行的(无序)集合上的汇总签名 64 位哈希值。HASH_AGG 从不返回 NULL,即使没有提供输入。将输入“哈希值”清空为 0

聚合哈希函数的一个用途是检测对一组值的更改,而无需比较单个旧值和新值。HASH_AGG 可以基于多个输入计算单个哈希值;几乎对其中一个输入的任何更改都可能导致 HASH_AGG 函数输出的更改。比较两个值列表通常需要对两个列表进行排序,但无论输入的顺序如何,HASH_AGG 都会生成相同的值。因为不需要对 HASH_AGG 的值进行排序,所以性能通常要快得多。

备注

HASH_AGG 不是 加密哈希函数,不应用作加密哈希函数。

如需加密,请使用 SHA 系列函数(在 字符串和二进制函数 中)。

另请参阅:

HASH

语法

聚合函数

HASH_AGG( [ DISTINCT ] <expr> [ , <expr2> ... ] )

HASH_AGG(*)
Copy

窗口函数

HASH_AGG( [ DISTINCT ] <expr> [ , <expr2> ... ] ) OVER ( [ PARTITION BY <expr3> ] )

HASH_AGG(*) OVER ( [ PARTITION BY <expr3> ] )
Copy

实参

exprN

表达式可以是任何 Snowflake 数据类型的常规表达式。

expr2

您可以包含其他表达式。

expr3

要分区的列(如果想将结果拆分为多个窗口)。

*

返回所有记录的所有列的聚合哈希值,包括具有 NULL 值的记录。您可以为聚合函数和窗口函数指定通配符。

当您将通配符传递给函数时,您可以使用表的名称或别名来限定通配符。例如,要传入名为 mytable 的表中的所有列,请指定以下内容:

(mytable.*)
Copy

您还可以使用 ILIKE 和 EXCLUDE 关键字进行筛选:

  • ILIKE 筛选条件,用于查找与指定模式匹配的列名。只允许使用一种模式。例如:

    (* ILIKE 'col1%')
    
    Copy
  • EXCLUDE 筛选出与指定列或列不匹配的列名。例如:

    (* EXCLUDE col1)
    
    (* EXCLUDE (col1, col2))
    
    Copy

使用这些关键字时,限定符有效。以下示例使用 ILIKE 关键字筛选出与表 mytable 中的模式 col1% 相匹配的所有列:

(mytable.* ILIKE 'col1%')
Copy

ILIKE 和 EXCLUDE 关键字不能组合在单个函数调用中。

对于此函数,ILIKE 和 EXCLUDE 关键字仅在 SELECT 列表或 GROUP BY 子句中有效。

关于 ILIKE 和 EXCLUDE 关键字的更多信息,请参阅 SELECT 中的“参数”部分。

返回

返回已签名的 64 位值 NUMBER (19,0)。

HASH_AGG 从不返回 NULL,即使对于 NULL 输入也是如此。

使用说明

  • HASH_AGG 计算整个表或查询结果或窗口的“指纹”。输入的任何更改都会以压倒性的概率影响 HASH_AGG 结果。这可用于快速检测对表内容或查询结果的变更。

    请注意,尽管可能性很小,但两个不同的输入表可能会为 HASH_AGG 产生相同的结果。如果需要确保生成相同 HASH_AGG 结果的两个表或查询结果确实包含相同的数据,则仍必须比较数据是否相等(例如,通过使用 MINUS 运算符)。有关更多详细信息,请参阅 集运算符

  • HASH_AGG 区分顺序(即输入表或查询结果中的行顺序不会影响 HASH_AGG 的结果)。但是,更改输入列的顺序 确实 会更改结果。

  • HASH_AGG 使用 HASH 函数对各个输入行进行哈希处理。此函数的显著特征延续到 HASH_AGG。特别是,从某种意义上说,HASH_AGG 是 稳定的,因为任何两行比较相等且具有兼容类型,都可以保证哈希为相同的值(即它们以相同的方式影响 HASH_AGG 结果)。

    例如,更改属于某个表的列的小数位数和精度不会更改该表上的 HASH_AGG 结果。有关详细信息,请参阅 HASH

  • 与大多数其他聚合函数相比,HASH_AGG 不忽略 NULL 输入(即 NULL 输入会影响 HASH_AGG 结果)。

  • 对于聚合函数和窗口函数,重复的行(包括重复的所有 NULL 行)都会影响结果。DISTINCT 关键字可用于抑制重复行的效果。

  • 当此函数作为窗口函数调用时,它不支持:

    • OVER 子句中的 ORDER BY 子句。

    • 显式窗口框架。

排序规则详细信息

No impact.

  • 如果两个字符串实际相同,但具有不同的排序规则规范,则它们具有相同的哈希值。换句话说,只有字符串(而不是排序规则规范)会影响哈希值。

  • 如果根据排序规则,两个字符串实际不同,但在比较时却被视为相等,则它们可能具有不同的哈希值。例如,使用不区分标点符号的排序规则的两个相同字符串通常具有不同的哈希值,因为只有字符串(而不是排序规则规范)会影响哈希值。

示例

此示例显示 NULLs 未被忽略:

SELECT HASH_AGG(NULL), HASH_AGG(NULL, NULL), HASH_AGG(NULL, NULL, NULL);
Copy
+----------------------+----------------------+----------------------------+
|       HASH_AGG(NULL) | HASH_AGG(NULL, NULL) | HASH_AGG(NULL, NULL, NULL) |
|----------------------+----------------------+----------------------------|
| -5089618745711334219 |  2405106413361157177 |       -5970411136727777524 |
+----------------------+----------------------+----------------------------+

此示例显示空输入哈希值为 0

SELECT HASH_AGG(NULL) WHERE 0 = 1;
Copy
+----------------+
| HASH_AGG(NULL) |
|----------------|
|              0 |
+----------------+

使用 HASH_AGG(*) 方便地汇总所有输入列:

SELECT HASH_AGG(*) FROM orders;
Copy
+---------------------+
|     HASH_AGG(*)     |
|---------------------|
| 1830986524994392080 |
+---------------------+

此示例显示支持分组汇总:

SELECT YEAR(o_orderdate), HASH_AGG(*)
  FROM ORDERS GROUP BY 1 ORDER BY 1;
Copy
+-------------------+----------------------+
| YEAR(O_ORDERDATE) |     HASH_AGG(*)      |
|-------------------+----------------------|
| 1992              | 4367993187952496263  |
| 1993              | 7016955727568565995  |
| 1994              | -2863786208045652463 |
| 1995              | 1815619282444629659  |
| 1996              | -4747088155740927035 |
| 1997              | 7576942849071284554  |
| 1998              | 4299551551435117762  |
+-------------------+----------------------+

此示例使用 DISTINCT 禁止重复行(重复行会影响 HASH_AGG 结果):

SELECT YEAR(o_orderdate), HASH_AGG(o_custkey, o_orderdate)
  FROM orders GROUP BY 1 ORDER BY 1;
Copy
+-------------------+----------------------------------+
| YEAR(O_ORDERDATE) | HASH_AGG(O_CUSTKEY, O_ORDERDATE) |
|-------------------+----------------------------------|
| 1992              | 5686635209456450692              |
| 1993              | -6250299655507324093             |
| 1994              | 6630860688638434134              |
| 1995              | 6010861038251393829              |
| 1996              | -767358262659738284              |
| 1997              | 6531729365592695532              |
| 1998              | 2105989674377706522              |
+-------------------+----------------------------------+
SELECT YEAR(o_orderdate), HASH_AGG(DISTINCT o_custkey, o_orderdate)
  FROM orders GROUP BY 1 ORDER BY 1;
Copy
+-------------------+-------------------------------------------+
| YEAR(O_ORDERDATE) | HASH_AGG(DISTINCT O_CUSTKEY, O_ORDERDATE) |
|-------------------+-------------------------------------------|
| 1992              | -8416988862307613925                      |
| 1993              | 3646533426281691479                       |
| 1994              | -7562910554240209297                      |
| 1995              | 6413920023502140932                       |
| 1996              | -3176203653000722750                      |
| 1997              | 4811642075915950332                       |
| 1998              | 1919999828838507836                       |
+-------------------+-------------------------------------------+

此示例计算状态不等于 'F' 和状态不等于 'P' 的订单的相应客户集分别相同的天数:

SELECT COUNT(DISTINCT o_orderdate) FROM orders;
Copy
+-----------------------------+
| COUNT(DISTINCT O_ORDERDATE) |
|-----------------------------|
| 2406                        |
+-----------------------------+
SELECT COUNT(o_orderdate)
  FROM (SELECT o_orderdate, HASH_AGG(DISTINCT o_custkey)
    FROM orders
    WHERE o_orderstatus <> 'F'
    GROUP BY 1
    INTERSECT
      SELECT o_orderdate, HASH_AGG(DISTINCT o_custkey)
        FROM orders
        WHERE o_orderstatus <> 'P'
        GROUP BY 1);
Copy
+--------------------+
| COUNT(O_ORDERDATE) |
|--------------------|
| 1143               |
+--------------------+

查询不考虑哈希冲突的可能性,因此实际天数可能略低。

语言: 中文