Categorias:

Funções de agregação , Funções de janela

HASH_AGG

Retorna um valor agregado de hash assinado de 64 bits sobre o conjunto (não ordenado) de linhas de entrada. HASH_AGG nunca retorna NULL, mesmo que nenhuma entrada seja fornecida. “Hashes” de entrada vazia para 0.

Um uso para funções de hash agregado é detectar mudanças em um conjunto de valores sem comparar os valores individuais antigos e novos. HASH_AGG pode calcular um único valor do hash baseado em muitas entradas; quase qualquer mudança em uma das entradas provavelmente resultará em uma mudança na saída da função HASH_AGG. Comparar duas listas de valores normalmente requer a ordenação de ambas as listas, mas HASH_AGG produz o mesmo valor independentemente da ordem das entradas. Como os valores não precisam ser classificados para HASH_AGG, o desempenho é normalmente muito mais rápido.

Nota

HASH_AGG não é uma função de hash criptográfico e não deve ser usada como tal.

Para fins criptográficos, utilizar as famílias de funções SHA (em Funções de cadeia de caracteres e binários).

Consulte também:

HASH

Sintaxe

Função de agregação

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

HASH_AGG(*)
Copy

Função de janela

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

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

Argumentos

exprN

A expressão pode ser uma expressão geral de qualquer tipo de dados do Snowflake.

expr2

É possível incluir expressões adicionais.

expr3

A coluna a ser dividida, se você quiser que o resultado seja dividido em várias janelas.

*

Retorna um valor de hash agregado sobre todas as colunas para todos os registros, incluindo registros com valores NULL. É possível especificar o curinga para a função de agregação e para a função de janela.

Ao passar um curinga para a função, você pode qualificar o curinga com o nome ou alias da tabela. Por exemplo, para passar todas as colunas da tabela nomeadas mytable, especifique o seguinte:

(mytable.*)
Copy

Também é possível usar as palavras-chave ILIKE e EXCLUDE para filtrar:

  • ILIKE filtra nomes de colunas que correspondem ao padrão especificado. Apenas um padrão é permitido. Por exemplo:

    (* ILIKE 'col1%')
    
    Copy
  • EXCLUDE filtra nomes de coluna que não correspondem à coluna ou colunas especificadas. Por exemplo:

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

Os qualificadores são válidos quando você usa essas palavras-chave. O exemplo a seguir usa a palavra-chave ILIKE para filtrar todas as colunas que correspondem ao padrão col1% na tabela mytable:

(mytable.* ILIKE 'col1%')
Copy

As palavras-chave ILIKE e EXCLUDE não podem ser combinadas em uma única chamada de função.

Para esta função, as palavras-chave ILIKE e EXCLUDE são válidas somente em uma lista SELECT ou cláusula GROUP BY.

Para obter mais informações sobre as palavras-chave ILIKE e EXCLUDE, consulte a seção «Parâmetros» em SELECT.

Retornos

Devolve um valor assinado de 64 bits como NUMBER(19,0).

HASH_AGG nunca retorna NULL, mesmo para entradas NULL.

Notas de uso

  • HASH_AGG calcula uma “impressão digital” em toda uma tabela ou janela ou resultado de consulta. Qualquer mudança na entrada influenciará o resultado de HASH_AGG com uma probabilidade esmagadora. Isso pode ser usado para detectar rapidamente mudanças no conteúdo das tabelas ou resultados de consultas.

    Note que é possível, embora muito improvável, que duas tabelas de entrada diferentes produzam o mesmo resultado para HASH_AGG. Se você precisar ter certeza de que duas tabelas ou resultados de consulta que produzem o mesmo resultado HASH_AGG realmente contêm os mesmos dados, você ainda deve comparar os dados quanto à igualdade (por exemplo, usando o operador MINUS). Para obter mais detalhes, consulte Operadores de conjuntos.

  • HASH_AGG não diferencia a ordem (ou seja, a ordem das linhas em uma tabela de entrada ou resultado de consulta não influencia o resultado de HASH_AGG). No entanto, alterar a ordem das colunas de entrada faz alterar o resultado.

  • HASH_AGG aplica hash nas linhas de entrada individuais usando a função HASH. Os recursos salientes desta função são transferidos para HASH_AGG. Em particular, o HASH_AGG é estável no sentido de que quaisquer duas linhas que comparam de forma igual e que tenham tipos compatíveis aplicam garantidamente hash no mesmo valor (ou seja, influenciam o resultado de HASH_AGG da mesma forma).

    Por exemplo, mudar a escala e a precisão de uma coluna que faz parte de alguma tabela, não altera o resultado de HASH_AGG sobre essa tabela. Consulte HASH para obter mais detalhes.

  • Ao contrário da maioria das outras funções agregadas, HASH_AGG não ignora entradas NULL (isto é, entradas NULL influenciam no resultado de HASH_AGG).

  • Tanto para a função agregada quanto para funções de janela, as linhas duplicadas, incluindo as linhas todas NULL duplicadas, influenciam o resultado. A palavra-chave DISTINCT pode ser usada para suprimir o efeito de linhas duplicadas.

  • Quando esta função é chamada como uma função de janela, ela não oferece suporte para:

    • Uma cláusula ORDER BY dentro da cláusula OVER.

    • Quadros de janela explícitos.

Detalhes do agrupamento

No impact.

  • Duas cadeias de caracteres que são idênticas mas têm especificações de agrupamento diferentes têm o mesmo valor do hash. Em outras palavras, apenas a cadeia de caracteres, não a especificação do agrupamento, afeta o valor do hash.

  • Duas cadeias de caracteres que são diferentes, mas que se comparam de maneira igual de acordo com um agrupamento, podem ter um valor do hash diferente. Por exemplo, duas cadeias de caracteres que são idênticas usando agrupamento que não identifica pontuação normalmente terão valores de hash diferentes porque apenas a cadeia de caracteres, não a especificação de agrupamento, afeta o valor de hash.

Exemplos

Este exemplo mostra que NULLs não são ignorados:

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 |
+----------------------+----------------------+----------------------------+

Este exemplo mostra que a entrada vazia é transformada em hashes para 0:

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

Use HASH_AGG(*) para agregar convenientemente em todas as colunas de entrada:

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

Este exemplo mostra que a agregação agrupada é compatível:

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  |
+-------------------+----------------------+

Este exemplo suprime linhas duplicadas usando DISTINCT (linhas duplicadas influenciam os resultados de 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                       |
+-------------------+-------------------------------------------+

Este exemplo calcula o número de dias em que os conjuntos correspondentes de clientes com pedidos com status diferente de 'F' e status diferente de 'P', respectivamente, são idênticos:

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               |
+--------------------+

A consulta não conta a possibilidade de colisões de hash, então o número real de dias pode ser um pouco menor.