Hive. GROUPING SETS 의 "함정"

4875 단어 HiveHQLSQL
앞서 하 이브 0.10 에 도 입 된 그룹 핑 세 츠 자구 의 특성 을 정리 하고 간단 한 구법 사용 체험 과 데이터 검증 을 했다.그러나 당시 에는 조금 복잡 한 상황 을 눈치 채 지 못 하고 실제 사용 과정 에서 한 방 맞 았 다.
       이 총 은 JOIN 이 조작 할 때 발생 했 습 니 다. 상황 은 이 렇 습 니 다. 저 는 Hive 표 datatable 의 a, b, c 이 세 필드 는 UV 와 VV 라 는 두 데 이 터 를 통계 하고 c 에서 b 로 말 아 올 린 다음 에 a 로 말 아 올 린 통계 가 필요 합 니 다.또한 필드 b 의 값 을 값 맵 으로 표시 하려 면 b 값 을 전문 적 으로 설명 하 는 다른 표 와 JOIN 을 통 해 이 루어 집 니 다.HQL 문 구 는 다음 과 같 습 니 다.
select
         t1.a_desc,
         if(t1.group_bitvector= 1, '   ', t2.b_desc) as b_desc,
         if(t1.group_bitvector= 1 or t1.group_bitvector = 3, '   ', t1.c_desc) as c_desc,
         t1.group_bitvector,
         t1.act_uv,
         t1.act_vv
from
(
         select
                   a_desc,
                   b,
                   c_desc,
                   grouping__id as group_bitvector,
                   count(distinctuer_ID) as act_uv,
                   (sum(if(vv_ID is null, 1, 0)) + sum(if(vv_ID = "", 1, 0)) + count(distinct if(vv_ID is not null, if(vv_ID != "", vv_ID, null), null))) as act_vv
         from
         (
                   select
                            (
                                     case a
                                               when 0 then 'str_val_1'
                                               when 1 then 'str_val_2'
                                               when 2 then 'str_val_3'
                                               else 'str_val_4'
                                     end    
                            )as a_desc,
                            b,
                            if(c= -2 or c = -1 or c = 9, 'c_desc1', 'c_desc2') as c_desc,
                            uer_ID,
                            vv_ID
                   from data_table
                   where a = xxx
         ) t
         group by a_desc, b, c_desc
         grouping sets (a_desc,(a_desc, b),(a_desc, b, c_desc))
) t1 join dim_table t2 on (t1.b = t2.b)

       데이터 가 튀 어 나 와 눈 깜짝 할 사이 에 정상 입 니 다. 자세히 보면 눈의 시련 을 견 디 지 못 합 니 다. groupbitvector 이 열 에 값 이 하나 부족 한 것 같 습 니 다. 이렇게 GROUPING SETS 에서 내 려 오 면 groupbitvector 는 1, 3, 7 이라는 세 개의 값 이 나 와 야 하 는데 나 온 데 이 터 는 1 이 없다. 즉, 맨 위 에 있 는 집합 (a 만 집합) 데이터 가 부족 하 다 는 것 이다!
       곰 곰 이 생각 하고 나 서 야 머리 를 두 드 려 이 미묘 한 잘못 을 발 견 했 습 니 다. 조인 군 은 데 이 터 를 버 렸 습 니 다!GROUPING SETS 는 GROUP BY 자구 에서 집합 에 참여 하지 않 은 열 을 NULL 로 설정 하지 않 습 니까? 이 NULL 값 들 은 JOIN 할 때 무정 하 게 버 려 집 니 다...이때 LEFT OUTER JOIN 은 용감하게 나 섰 다. 이 는 내 가 원래 의 JOIN (내부 연결) 을 교체 하면 데이터 가 걸 러 지 는 문 제 를 예 쁘 게 제거 할 수 있다 고 말 했다.
 
select
         t1.a_desc,
         if(t1.group_bitvector= 1, '   ', t2.b_desc) as b_desc,
         if(t1.group_bitvector= 1 or t1.group_bitvector = 3, '   ', t1.c_desc) as c_desc,
         t1.group_bitvector,
         t1.act_uv,
         t1.act_vv
from
(
         select
                   a_desc,
                   b,
                   c_desc,
                   grouping__id as group_bitvector,
                   count(distinctuer_ID) as act_uv,
                   (sum(if(vv_ID is null, 1, 0)) + sum(if(vv_ID = "", 1, 0)) + count(distinct if(vv_ID is not null, if(vv_ID != "", vv_ID, null), null))) as act_vv
         from
         (
                   select
                            (
                                     case a
                                               when 0 then 'str_val_1'
                                               when 1 then 'str_val_2'
                                               when 2 then 'str_val_3'
                                               else 'str_val_4'
                                     end    
                            )as a_desc,
                            b,
                            if(c= -2 or c = -1 or c = 9, 'c_desc1', 'c_desc2') as c_desc,
                            uer_ID,
                            vv_ID
                   from data_table
                   where a = xxx
         ) t
         group by a_desc, b, c_desc
         grouping sets (a_desc,(a_desc, b),(a_desc, b, c_desc))
) t1 left outer join dim_table t2 on (t1.b = t2.b)

       이 장면 에서 groupingid 이 함수 의 용도 도 나 타 났 습 니 다. 그것 이 없 으 면 데이터 가 부족 한 문 제 는 더욱 무시 되 기 쉽 습 니 다.
       마지막 으로 다 중 또는 다 열 로 JOIN 을 진행 할 경우 특히 이 문 제 를 주의해 야 합 니 다 ~ ~ LEFT OUTER JOIN 과 GROUPINGID 의 반환 값 은 조회 데 이 터 를 명확 하 게 표현 하고 GROUP 그룹 이 구분 하 는 수 요 를 할 수 있 습 니 다.
       마지막, 그리고 작은 지뢰: goupingid 의 반환 값 은 직관 적 으로 보 이 는 정형 이 아니 라 문자열 형식 입 니 다!때때로 Hive 는 자동 으로 정형 과 문자열 유형 간 의 해석 을 처리 합 니 다. 왜냐하면 문자열 의 많은 연산 과 정형 연산 은 매우 비슷 하기 때 문 입 니 다.그러나 가끔 은 Hive 도 우리 에 게 처리 하지 않 습 니 다. 예 를 들 어 케이스... when... then.. end 자 구 를 사용 할 때 필드 데이터 형식 이 엄 격 히 같 아야 합 니 다. 그렇지 않 으 면 오 류 를 보고 할 수 있 습 니 다. 비록 이 오 류 는 명확 하고 조사 하기 쉽 습 니 다.

좋은 웹페이지 즐겨찾기