- 카테고리:
GROUP BY GROUPING SETS¶
GROUP BY GROUPING SETS는 단일 문에서 여러 group-by 절을 계산하는 GROUP BY 절의 강력한 확장입니다. 그룹 세트는 차원 열 세트입니다.
GROUP BY GROUPING SETS는 동일한 결과 세트에서 두 개 이상의 GROUP BY 작업의 UNION
과 동등합니다.
GROUP BY GROUPING SETS(a)
는 단일 그룹화 세트 연산GROUP BY a
와 동등합니다.GROUP BY GROUPING SETS(a,b)
는GROUP BY a UNION ALL GROUP BY b
와 동등합니다.
구문¶
SELECT ...
FROM ...
[ ... ]
GROUP BY GROUPING SETS ( groupSet [ , groupSet [ , ... ] ] )
[ ... ]
여기서:
groupSet ::= { <column_alias> | <position> | <expr> }
사용법 노트¶
Snowflake는 동일한 쿼리 블록에서 최대 128개의 그룹화 세트를 허용합니다.
출력에는 일반적으로 일부 NULL 값이 포함됩니다.
GROUP BY ROLLUP
은 각각 다른 기준으로 그룹화된 둘 이상의 결과 세트의 결과를 병합하기 때문에, 한 결과 세트에 단일 값이 있는 일부 열은 다른 결과 세트에 많은 해당 값을 가질 수 있습니다. 예를 들어, 부서별로 그룹화된 직원 세트를 직위별로 그룹화한 세트와 함께UNION
을 수행하는 경우, 가장 높은 직위를 가진 세트의 구성원이 반드시 같은 부서에 있는 것은 아니므로 부서_이름의 값이 NULL로 설정됩니다. 이러한 이유로 다음 예시에는 NULL이 포함되어 있습니다.
예¶
이 예에서는 재해 지원을 위해 훈련된 간호사에 대한 정보 테이블을 사용합니다. 이 모든 간호사는 간호사 면허(예: RN은 “등록 간호사” 면허가 있음)와 수색 및 구조, 무선 통신 등의 재해 관련 전문 분야의 추가 면허를 가지고 있습니다. 이 예에서는 두 가지 카테고리의 면허만 단순화하여 사용합니다.
간호: RN(등록 간호사) 및 LVN(면허가 있는 직업 간호사).
아마추어(“햄”) 무선: 햄 무선 면허에는 “Technician”, “General”, “Amateur Extra”가 포함됩니다.
다음은 테이블을 만들고 로딩하는 명령입니다.
CREATE or replace TABLE nurses ( ID INTEGER, full_name VARCHAR, medical_license VARCHAR, -- LVN, RN, etc. radio_license VARCHAR -- Technician, General, Amateur Extra ) ; INSERT INTO nurses (ID, full_name, medical_license, radio_license) VALUES (201, 'Thomas Leonard Vicente', 'LVN', 'Technician'), (202, 'Tamara Lolita VanZant', 'LVN', 'Technician'), (341, 'Georgeann Linda Vente', 'LVN', 'General'), (471, 'Andrea Renee Nouveau', 'RN', 'Amateur Extra') ;
이 쿼리는 GROUP BY GROUPING SETS
를 사용합니다.
SELECT COUNT(*), medical_license, radio_license FROM nurses GROUP BY GROUPING SETS (medical_license, radio_license);출력:
처음 두 행은 RN 및 LVN(간호 면허의 두 가지 유형) 수를 보여줍니다. 이 두 행에 대한 RADIO_LICENSE 열의 NULL 값은 의도적입니다. 쿼리는 해당 무선 면허와 관계없이 모든 LVN(및 모든 RN을 함께)을 그룹화하므로, 결과는 해당 행에 그룹화된 모든 LVN 또는 RN에 반드시 적용되는 각 행의 RADIO_LICENSE 열에 하나의 값을 표시할 수 없습니다.
다음 세 행은 각 유형의 햄 무선 면허(“Technician”, “General”, “Amateur Extra”)를 가진 간호사의 수를 보여줍니다. 이러한 세 행 각각의 MEDICAL_LICENSE에 대한 NULL 값은 의도적입니다. 단일 의료 면허가 각 행의 모든 구성원에게 반드시 적용되는 것은 아니기 때문입니다.
+----------+-----------------+---------------+ | COUNT(*) | MEDICAL_LICENSE | RADIO_LICENSE | |----------+-----------------+---------------| | 3 | LVN | NULL | | 1 | RN | NULL | | 2 | NULL | Technician | | 1 | NULL | General | | 1 | NULL | Amateur Extra | +----------+-----------------+---------------+
다음 예에서는 일부 열에 NULL 값이 포함된 경우 어떤 일이 발생하는지 보여줍니다. 아직 햄 무선 면허가 없는 새 간호사 3명을 추가하여 시작합니다.
INSERT INTO nurses (ID, full_name, medical_license, radio_license) VALUES (101, 'Lily Vine', 'LVN', NULL), (102, 'Larry Vancouver', 'LVN', NULL), (172, 'Rhonda Nova', 'RN', NULL) ;그런 다음 이전과 동일한 쿼리를 실행합니다.
SELECT COUNT(*), medical_license, radio_license FROM nurses GROUP BY GROUPING SETS (medical_license, radio_license);출력:
처음 5줄은 이전 쿼리와 동일합니다.
마지막 줄의 경우, 처음에는 혼란스러울 수 있습니다. 두 열에 모두 NULL이 있는 줄이 왜 존재하는지, 그리고 모든 값이 NULL이면 COUNT(*)가 왜 3인지에 관해 의문이 발생하기 때문입니다.
대답은, 해당 행의 RADIO_LICENSE 열에서 NULL이 발생하는 이유는 세 간호사에게 무선 면허가 없기 때문이라는 것입니다. (“SELECT DISTINCT RADIO_LICENSE FROM 간호사”는 이제 “Technician”, “General”, “Amateur Extra”, “NULL”이라는 4가지 고유한 값을 반환합니다.)
MEDICAL_LICENSES 열의 NULL은 이전 쿼리 결과에서 NULL 값이 발생한 것과 같은 이유로 발생합니다. 즉, 이 행에서 계산된 간호사는 다른 MEDICAL_LICENSES를 가지므로 하나의 값(“RN” 또는 “LVN”)이 이 행에 계산된 모든 간호사에게 반드시 적용되는 것은 아닙니다.
+----------+-----------------+---------------+ | COUNT(*) | MEDICAL_LICENSE | RADIO_LICENSE | |----------+-----------------+---------------| | 5 | LVN | NULL | | 2 | RN | NULL | | 2 | NULL | Technician | | 1 | NULL | General | | 1 | NULL | Amateur Extra | | 3 | NULL | NULL | +----------+-----------------+---------------+
원하는 경우, 이 출력을 GROUPING SETS
절이 없는 GROUP BY
의 출력과 비교할 수 있습니다.
SELECT COUNT(*), medical_license, radio_license FROM nurses GROUP BY medical_license, radio_license;출력:
+----------+-----------------+---------------+ | COUNT(*) | MEDICAL_LICENSE | RADIO_LICENSE | |----------+-----------------+---------------| | 2 | LVN | Technician | | 1 | LVN | General | | 1 | RN | Amateur Extra | | 2 | LVN | NULL | | 1 | RN | NULL | +----------+-----------------+---------------+