카테고리:

집계 함수 , 윈도우 함수

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

사용법 노트

  • HASH_AGG(*) 양식은 모든 열에 대해 계산합니다. 이는 집계 함수와 윈도우 함수 모두에서 작동합니다.

  • 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.

  • 동일하지만 데이터 정렬 사양이 다른 두 문자열은 같은 해시 값을 갖습니다. 즉, 데이터 정렬 사양이 아니라 문자열만 해시 값에 영향을 줍니다.

  • 서로 다르지만 데이터 정렬에 따라 동일하게 비교되는 두 문자열은 다른 해시 값을 가질 수 있습니다. 예를 들어, 구두점을 구분하지 않는 데이터 정렬을 사용하는 동일한 두 문자열은 일반적으로, 다른 해시 값을 갖게 됩니다. 데이터 정렬 사양이 아니라 문자열만 해시 값에 영향을 미치기 때문입니다.

NULL은 절대 무시되지 않습니다.

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

쿼리는 해시 충돌 가능성을 고려하지 않으므로 실제 일수는 약간 더 적을 수 있습니다.