Kategorien:

Aggregatfunktionen , Fensterfunktionen

HASH_AGG

Gibt einen aggregierten, signierten 64-Bit-Hash-Wert für die (ungeordnete) Menge von Eingabezeilen zurück. HASH_AGG gibt niemals NULL zurück, auch wenn keine Eingabe bereitgestellt wird. Leere Eingabe „hasht“ zu 0.

Ein Anwendungsfall für Hash-Aggregatfunktionen ist das Erkennen von Änderungen an einer Gruppe von Werten, ohne die einzelnen alten und neuen Werte zu vergleichen. HASH_AGG kann aus vielen Eingabewerten einen einzigen Hash-Wert berechnen, wobei wahrscheinlich fast jede Änderung an einem der Eingabewerte zu einer Änderung des Ausgabewerts der HASH_AGG-Funktion führt. Beim Vergleich von zwei Wertelisten müssen normalerweise beide Listen sortiert werden, HASH_AGG erzeugt jedoch unabhängig von der Reihenfolge der Eingaben denselben Wert. Da die Werte nicht nach HASH_AGG sortiert werden müssen, ist die Leistung normalerweise deutlich schneller.

Bemerkung

HASH_AGG ist keine kryptografische Hashfunktion und sollte nicht als solche verwendet werden.

Nutzen Sie für kryptografische Zwecke die SHA-Funktionsfamilie (siehe Zeichenfolgen- und Binärfunktionen).

Siehe auch::

HASH

Syntax

Aggregatfunktion

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

HASH_AGG(*)
Copy

Fensterfunktionen

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

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

Argumente

exprN

Der Ausdruck kann ein allgemeiner Ausdruck eines beliebigen Snowflake-Datentyps sein.

expr2

Sie können zusätzliche Ausdrücke einfügen.

expr3

Die Spalte für die Partitionierung, wenn das Ergebnis auf mehrere Fenster aufgeteilt werden soll.

*

Gibt einen aggregierten Hashwert über alle Spalten für alle Datensätze zurück, einschließlich der Datensätze mit NULL-Werten. Sie können den Platzhalter sowohl für die Aggregatfunktion als auch für die Fensterfunktion angeben.

Wenn Sie einen Platzhalter an die Funktion übergeben, können Sie den Platzhalter mit dem Namen oder Alias für die Tabelle qualifizieren. Um beispielsweise alle Spalten aus der Tabelle mytable zu übergeben, geben Sie Folgendes ein:

(mytable.*)
Copy

Sie können auch die Schlüsselwörter ILIKE und EXCLUDE zum Filtern verwenden:

  • ILIKE filtert nach Spaltennamen, die dem angegebenen Muster entsprechen. Es ist nur ein Muster erlaubt. Beispiel:

    (* ILIKE 'col1%')
    
    Copy
  • EXCLUDE filtert Spaltennamen heraus, die nicht mit der angegebenen Spalte oder den angegebenen Spalten übereinstimmen. Beispiel:

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

Qualifizierer sind gültig, wenn Sie diese Schlüsselwörter verwenden. Das folgende Beispiel verwendet das Schlüsselwort ILIKE, um nach allen Spalten zu filtern, die dem Muster col1% in der Tabelle mytable entsprechen:

(mytable.* ILIKE 'col1%')
Copy

Die Schlüsselwörter ILIKE und EXCLUDE können nicht in einem einzigen Funktionsaufruf kombiniert werden.

Für diese Funktion sind die Schlüsselwörter ILIKE und EXCLUDE nur in einer SELECT-Liste oder GROUP BY-Klausel gültig.

Weitere Informationen zu den Schlüsselwörtern ILIKE und EXCLUDE finden Sie im Abschnitt „Parameter“ unter SELECT.

Rückgabewerte

Gibt einen vorzeichenbehafteten 64-Bit-Wert als NUMBER(19,0) zurück.

HASH_AGG gibt niemals NULL zurück, selbst bei NULL-Eingaben.

Nutzungshinweise

  • HASH_AGG berechnet einen „Fingerabdruck“ für eine ganze Tabelle oder ein Abfrageergebnis. Jede Änderung an der Eingabe beeinflusst das Ergebnis von HASH_AGG mit überwältigender Wahrscheinlichkeit. So lassen sich Änderungen an Tabelleninhalten oder Abfrageergebnissen schnell erkennen.

    Beachten Sie, dass es möglich, wenn auch sehr unwahrscheinlich ist, dass zwei verschiedene Eingabetabellen dasselbe Ergebnis für HASH_AGG liefern. Wenn Sie überprüfen möchten, ob zwei Tabellen oder Abfrageergebnisse, die dasselbe HASH_AGG-Ergebnis liefern, tatsächlich dieselben Daten enthalten, müssen Sie die Daten weiter hinsichtlich ihrer Gleichheit vergleichen (z. B. mit dem Operator MINUS). Weitere Details dazu finden Sie unter Mengenoperatoren.

  • HASH_AGG ist nicht sensibel für die Reihenfolge (d. h. die Reihenfolge von Zeilen in einer Eingabetabelle oder in einem Abfrageergebnis hat keinen Einfluss auf das Ergebnis von HASH_AGG). Durch Ändern der Reihenfolge von Eingabespalten wird das Ergebnis jedoch geändert.

  • HASH_AGG „hasht“ einzelne Eingabezeilen mithilfe der Funktion HASH. Die herausragenden Merkmale dieser Funktion werden auf HASH_AGG übertragen. Insbesondere ist HASH_AGG in dem Sinne stabil, dass beliebige zwei Zeilen, die gleiche Werte haben und kompatible Typen aufweisen, garantiert auf den gleichen Wert gehasht werden (d. h. sie beeinflussen das Ergebnis von HASH_AGG auf gleiche Weise).

    Wenn Sie beispielsweise die Skalierung und Genauigkeit einer Spalte ändern, die Teil einer Tabelle ist, ändert sich das Ergebnis von HASH_AGG für die Tabelle nicht. Weitere Informationen finden Sie unter HASH.

  • Im Gegensatz zu den meisten anderen Aggregatfunktionen ignoriert HASH_AGG NULL-Eingaben nicht (d. h. NULL-Eingaben beeinflussen das Ergebnis von HASH_AGG).

  • Sowohl für die Aggregatfunktion als auch für die Fensterfunktionen wirken sich doppelte Zeilen, einschließlich Komplett-NULL-Zeilen, auf das Ergebnis aus. Das Schlüsselwort DISTINCT kann verwendet werden, um die Wirkung duplizierter Zeilen zu unterdrücken.

  • Wenn diese Funktion als Fensterfunktion aufgerufen wird, wird sie nicht unterstützt:

    • Eine ORDER BY-Klausel innerhalb der OVER-Klausel.

    • Explizite Fensterrahmen.

Sortierungsdetails

No impact.

  • Zwei identische Zeichenfolgen mit unterschiedlichen Sortierungsspezifikationen haben denselben Hashwert. Mit anderen Worten: Nur die Zeichenfolge, nicht die Sortierungsspezifikation, wirkt sich auf den Hashwert aus.

  • Zwei Zeichenfolgen, die unterschiedlich sind, aber gemäß einer Sortierung gleich sind, können unterschiedliche Hashwerte aufweisen. Beispielsweise haben zwei Zeichenfolgen, die bei Verwendung einer Sortierung ohne Berücksichtigung von Satzzeichen identisch sind, normalerweise unterschiedliche Hashwerte, da sich nur die Zeichenfolge und nicht die Sortierungsspezifikation auf den Hashwert auswirkt.

Beispiele

Dieses Beispiel zeigt, dass NULLs nicht ignoriert werden:

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

Dieses Beispiel zeigt, dass eine leere Eingabe zu 0 „hasht“:

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

Verwenden von HASH_AGG(*) zum einfachen Aggregieren aller Eingabespalten:

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

Dieses Beispiel zeigt, dass die gruppierte Aggregation unterstützt wird:

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

In diesem Beispiel werden doppelte Zeilen mit DISTINCT unterdrückt (doppelte Zeilen beeinflussen die Ergebnisse von 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                       |
+-------------------+-------------------------------------------+

In diesem Beispiel wird die Anzahl der Tage berechnet, an denen die übereinstimmenden Kundengruppen mit Aufträgen, deren Status ungleich 'F' und ungleich 'P' ist, identisch sind:

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

Bei der Abfrage wird die Möglichkeit von Hash-Kollisionen nicht berücksichtigt wird, sodass die tatsächliche Anzahl von Tagen möglicherweise etwas niedriger ist.