Categorias:

Funções de hash

HASH

Retorna um valor de hash assinado de 64 bits. Note que HASH nunca retorna NULL, mesmo para entradas NULL.

Os usos possíveis para a função HASH incluem:

  • Converter valores de dados inclinados em valores que provavelmente serão distribuídos de forma mais aleatória ou mais uniforme.

    Por exemplo, você pode ter um grupo de valores altamente inclinados e gerar um conjunto de valores que são mais prováveis de serem distribuídos aleatoriamente ou uniformemente distribuídos.

  • Colocar dados em buckets. Como o hashing pode converter valores de dados inclinados em valores mais próximos a valores distribuídos uniformemente, você pode usar o hashing para ajudar a tomar valores inclinados e criar buckets de tamanho aproximadamente uniforme.

    Se o hashing sozinho não for suficiente para obter o número de buckets distintos que você deseja, você pode combinar o hashing com as funções ROUND ou WIDTH_BUCKET.

Nota

HASH é uma função proprietária que aceita um número variável de expressões de entrada de tipos arbitrários e retorna um valor assinado. Não é uma função de hash criptográfico e não deve ser usada como tal.

As funções criptográficas de hash têm algumas propriedades que esta função não tem, por exemplo:

  • O hashing criptográfico de um valor não pode ser invertido para encontrar o valor original.

  • Dado um valor, é inviável encontrar outro valor com o mesmo hash criptográfico.

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_AGG

Sintaxe

HASH( <expr> [ , <expr> ... ] )

HASH(*)
Copy

Argumentos

expr

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

*

Retorna um único valor com hash com base em todas as colunas em cada registro, incluindo registros com valores NULL.

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 nunca retorna NULL, mesmo para entradas NULL.

Notas de uso

  • HASH é estável de forma a garantir que:

    • Quaisquer dois valores do tipo NUMBER que se comparem igualmente, terão o mesmo valor de hash, mesmo que os respectivos tipos tenham precisão e/ou escala diferentes.

    • Quaisquer dois valores do tipo FLOAT que possam ser convertidos em NUMBER(38, 0) sem perda de precisão terão o mesmo valor. Por exemplo, todos os seguintes retornam o mesmo valor do hash:

      • HASH(10::NUMBER(38,0))

      • HASH(10::NUMBER(5,3))

      • HASH(10::FLOAT)

    • Quaisquer dois valores do tipo TIMESTAMP_TZ que se comparem igualmente, terão o mesmo valor do hash, mesmo que os carimbos de data/hora sejam de fusos horários diferentes.

    • Esta garantia também se aplica aos valores NUMBER, FLOAT e TIMESTAMP_TZ dentro de uma coluna VARIANT.

    • Observe que esta garantia não se aplica a outras combinações de tipos, mesmo que existam conversões implícitas entre os tipos. Por exemplo, com uma probabilidade esmagadora, o seguinte não retornará os mesmos valores do hash, mesmo que 10 = '10' após a conversão implícita:

      • HASH(10)

      • HASH('10')

  • HASH(*) significa criar um único valor do hash baseado em todas as colunas da linha.

  • Não use HASH para criar chaves únicas. HASH tem uma resolução finita de 64 bits, e garante o retorno de valores não únicos se mais de 2^64 valores forem inseridos (por exemplo, para uma tabela com mais de 2^64 linhas). Na prática, se a entrada estiver na ordem de 2^32 linhas (aproximadamente 4 bilhões de linhas) ou mais, é razoavelmente provável que a função retorne pelo menos um valor duplicado.

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

SELECT HASH(SEQ8()) FROM TABLE(GENERATOR(rowCount=>10));
Copy
+----------------------+
|         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);
Copy
+---------------------+------------------------+-----------------------+---------------------+
|            HASH(10) | HASH(10::NUMBER(38,0)) | HASH(10::NUMBER(5,3)) |     HASH(10::FLOAT) |
|---------------------+------------------------+-----------------------+---------------------|
| 1599627706822963068 |    1599627706822963068 |   1599627706822963068 | 1599627706822963068 |
+---------------------+------------------------+-----------------------+---------------------+
SELECT HASH(10), HASH('10');
Copy
+---------------------+---------------------+
|            HASH(10) |          HASH('10') |
|---------------------+---------------------|
| 1599627706822963068 | 3622494980440108984 |
+---------------------+---------------------+
SELECT HASH(null), HASH(null, null), HASH(null, null, null);
Copy
+---------------------+--------------------+------------------------+
|          HASH(NULL) |   HASH(NULL, NULL) | HASH(NULL, NULL, NULL) |
|---------------------+--------------------+------------------------|
| 8817975702393619368 | 953963258351104160 |    2941948363845684412 |
+---------------------+--------------------+------------------------+

O exemplo abaixo mostra que mesmo que a tabela contenha várias colunas, HASH(*) retorna um único valor por linha.

CREATE TABLE orders (order_ID INTEGER, customer_ID INTEGER, order_date ...);

...

SELECT HASH(*) FROM orders LIMIT 10;
Copy
+-----------------------+
|        HASH(*)        |
|-----------------------|
|  -3527903796973745449 |
|  6296330861892871310  |
|  6918165900200317484  |
|  -2762842444336053314 |
|  -2340602249668223387 |
|  5248970923485160358  |
|  -5807737826218607124 |
|  428973568495579456   |
|  2583438210124219420  |
|  4041917286051184231  |
+ ----------------------+