カテゴリ:

集計関数ウィンドウ関数

HASH_AGG

入力行の(順序付けられていない)セットの符号付き64ビットハッシュ値の集約を返します。HASH_AGG は、入力が提供されない場合でも、 NULLを返しません。空の入力は 0 に「ハッシュ」されます。

集約ハッシュ関数の用途の1つは、個々の古い値と新しい値を比較せずに、一連の値の変更を検出することです。HASH_AGG は、多くの入力に基づいて単一のハッシュ値を計算できます。入力の1つを変更すると、HASH_AGG 関数の出力が変更される可能性があります。通常、2つの値のリストを比較するには両方のリストを並べ替える必要がありますが、 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

使用上の注意

  • フォーム HASH_AGG(*)は、すべての列について計算します。これは、集計関数とウィンドウ関数の両方で機能します。

  • HASH_AGG テーブル全体またはクエリ結果またはウィンドウに対して「フィンガープリント」を計算します。入力に対する変更は、圧倒的な確率で HASH_AGG の結果に影響します。これを使用して、テーブルの内容またはクエリ結果の変更をすばやく検出できます。

    非常にまれですが、2つの異なる入力テーブルが HASH_AGG に対して同じ結果を生成する可能性があります。同じ HASH_AGG の結果を生成する2つのテーブルまたはクエリ結果に実際に同じデータが含まれていることを確認する必要がある場合、データを比較する必要があります( MINUS 演算子を使用など)。詳細については、 集合演算子 をご参照ください。

  • HASH_AGG は、順序に依存 しません (入力テーブルまたはクエリ結果の行の順序 はHASH_AGGの結果に影響しません)。ただし、入力列の順序を変更すると、結果が 変化します

  • HASH_AGG は、 HASH 関数を使用して、個々の入力行をハッシュします。この関数の顕著な特徴は HASH_AGG に引き継がれます。特に、 HASH_AGG は、同等で互換性のあるタイプを持つ2つの行が同じ値にハッシュされることが保証されるという意味で 安定 しています( HASH_AGG の結果に同じように影響します)。

    例えば、あるテーブルの一部の列のスケールと精度を変更しても、そのテーブルの HASH_AGG の結果は変更されません。詳細については HASH をご参照ください。

  • 他のほとんどの集計関数とは異なり、 HASH_AGG は NULL 入力を無視しません(つまり、 NULL 入力は HASH_AGGの結果に影響します)。

  • 集計関数とウィンドウ関数の両方で、重複するすべてのNULL 行を含む重複行が結果に影響します。 DISTINCT キーワードを使用して、重複行の影響を抑制できます。

  • ウィンドウ関数として使用する場合、

    • この関数は次をサポートしていません。

      • OVER()句のORDER BY サブ句。

      • ウィンドウフレーム。

照合の詳細

No impact.

  • 同一だが照合仕様が異なる2つの文字列は、同じハッシュ値を持ちます。つまり、照合仕様ではなく文字列のみがハッシュ値に影響します。

  • 異なる2つの文字列が照合では同等に比較され、異なるハッシュ値を持つ場合があります。例えば、句読点に依存しない照合を使用した同一の2つの文字列のハッシュ値に影響するのは照合仕様ではなく文字列のみであるため、通常は異なるハッシュ値になります。

NULLs が無視されることはありません。

select hash_agg(null), hash_agg(null, null), hash_agg(null, null, null);

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

空の入力は 0 に「ハッシュ」されます。

select hash_agg(null) where 0 = 1;

----------------+
 HASH_AGG(NULL) |
----------------+
 0              |
----------------+
Copy

HASH_AGG(*)を使用して、すべての入力列を簡単に集約します。

select hash_agg(*) from orders;

---------------------+
     HASH_AGG(*)     |
---------------------+
 1830986524994392080 |
---------------------+
Copy

グループ化された集計がサポートされています。

select year(o_orderdate), hash_agg(*) from orders group by 1 order by 1;

-------------------+----------------------+
 YEAR(O_ORDERDATE) |     HASH_AGG(*)      |
-------------------+----------------------+
 1992              | 4367993187952496263  |
 1993              | 7016955727568565995  |
 1994              | -2863786208045652463 |
 1995              | 1815619282444629659  |
 1996              | -4747088155740927035 |
 1997              | 7576942849071284554  |
 1998              | 4299551551435117762  |
-------------------+----------------------+
Copy

DISTINCT を使用して重複行を抑制します(重複行は HASH_AGGの結果に影響します)。

select year(o_orderdate), hash_agg(o_custkey, o_orderdate) from orders group by 1 order by 1;

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

-------------------+-------------------------------------------+
 YEAR(O_ORDERDATE) | HASH_AGG(DISTINCT O_CUSTKEY, O_ORDERDATE) |
-------------------+-------------------------------------------+
 1992              | -8416988862307613925                      |
 1993              | 3646533426281691479                       |
 1994              | -7562910554240209297                      |
 1995              | 6413920023502140932                       |
 1996              | -3176203653000722750                      |
 1997              | 4811642075915950332                       |
 1998              | 1919999828838507836                       |
-------------------+-------------------------------------------+
Copy

この最後の例では、ステータスが 'F' に等しくない注文と、ステータスが 'P' に等しくない注文に対応する顧客のセットが同一である日数を計算します。

select count(distinct o_orderdate) from orders;

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

--------------------+
 COUNT(O_ORDERDATE) |
--------------------+
 1143               |
--------------------+
Copy

クエリはハッシュ衝突の可能性を考慮していないため、実際の日数はわずかに短くなる可能性があります。