HASH_AGG¶
(순서 없는) 입력 행 세트에 대해 부호 있는 집계 64비트 해시 값을 반환합니다. HASH_AGG는 절대 NULL을 반환하지 않습니다. 입력이 제공되지 않은 경우에도 마찬가지입니다. 입력 “해시”를 0
으로 비웁니다.
집계 해시 함수의 한 가지 용도는 개별 이전 값과 새 값을 비교하지 않고 값 세트의 변경 사항을 감지하는 것입니다. HASH_AGG는 많은 입력을 기반으로 단일 해시 값을 계산할 수 있습니다. 입력 중 하나에 대한 거의 모든 변경으로 인해 HASH_AGG 함수의 출력이 변경될 수 있습니다. 두 값 목록을 비교하려면 일반적으로 두 목록을 모두 정렬해야 하지만, HASH_AGG는 입력 순서와 관계없이 동일 값을 생성합니다. HASH_AGG에 대해 값을 정렬할 필요가 없기 때문에 일반적으로 성능이 훨씬 빠릅니다.
- 참고 항목:
구문¶
집계 함수
HASH_AGG( [ DISTINCT ] <expr> [ , <expr2> ... ] )
HASH_AGG(*)
윈도우 함수
HASH_AGG( [ DISTINCT ] <expr> [ , <expr2> ... ] ) OVER ( [ PARTITION BY <expr3> ] )
HASH_AGG(*) OVER ( [ PARTITION BY <expr3> ] )
사용법 노트¶
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 | ----------------------+----------------------+----------------------------+
입력 해시를 0
으로 비웁니다.
select hash_agg(null) where 0 = 1; ----------------+ HASH_AGG(NULL) | ----------------+ 0 | ----------------+
HASH_AGG(*)를 사용하여 모든 입력 열에 대해 편리하게 집계합니다.
select hash_agg(*) from orders; ---------------------+ HASH_AGG(*) | ---------------------+ 1830986524994392080 | ---------------------+
그룹화된 집계가 지원됩니다.
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 | -------------------+----------------------+
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 | -------------------+-------------------------------------------+
이 마지막 예에서는 상태가 '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 | --------------------+쿼리는 해시 충돌 가능성을 고려하지 않으므로 실제 일수는 약간 더 적을 수 있습니다.