복붙노트

[HADOOP] 하이브에 데이터를 조 변경 / 피벗하는 방법은 무엇입니까?

HADOOP

하이브에 데이터를 조 변경 / 피벗하는 방법은 무엇입니까?

하이브에 데이터를 변환 할 직접적인 방법이 없다는 것을 알고 있습니다. 나는이 질문을 따른다. 하이브에 데이터를 옮겨 놓을 방법이 있는가? , 거기에 최종 답이 없기 때문에 모든 것을 얻을 수는 없습니다.

이것은 내가 가지고있는 테이블이다.

 | ID   |   Code   |  Proc1   |   Proc2 | 
 | 1    |    A     |   p      |   e     | 
 | 2    |    B     |   q      |   f     |
 | 3    |    B     |   p      |   f     |
 | 3    |    B     |   q      |   h     |
 | 3    |    B     |   r      |   j     |
 | 3    |    C     |   t      |   k     |

여기서 Proc1은 여러 개의 값을 가질 수 있습니다. ID, 코드 및 Proc1은 함께이 테이블의 고유 키를 형성합니다. Proc1의 각 고유 값이 새 열이되도록이 테이블을 피벗 / 조바꿈하고 Proc2의 해당 값이 해당 행의 해당 열 값입니다. 본질적으로, 나는 다음과 같은 것을 얻으려고 노력하고있다.

 | ID   |   Code   |  p   |   q |  r  |   t |
 | 1    |    A     |   e  |     |     |     |
 | 2    |    B     |      |   f |     |     |
 | 3    |    B     |   f  |   h |  j  |     |
 | 3    |    C     |      |     |     |  k  |

새로 변환 된 표에서 ID와 코드 만 기본 키입니다. 위에서 언급 한 티켓에서 to_map UDAF를 사용하여 멀리까지 얻을 수있었습니다. (면책 조항 - 올바른 방향으로 나아갈 수는 없지만 여기에 언급 할 수는 있습니다.)

 | ID   |   Code   |  Map_Aggregation   | 
 | 1    |    A     |   {p:e}            |
 | 2    |    B     |   {q:f}            |
 | 3    |    B     |   {p:f, q:h, r:j } |  
 | 3    |    C     |   {t:k}            |

그러나이 단계에서 피벗 / 트랜스 포즈 테이블로 이동하는 방법을 모릅니다. 진행 방법에 대한 도움은 아주 좋습니다! 감사.

해결법

  1. ==============================

    1.다음은 하이브의 내부 UDF 함수 인 "map"을 사용하여이 문제를 해결하기 위해 사용한 접근 방식입니다.

    다음은 하이브의 내부 UDF 함수 인 "map"을 사용하여이 문제를 해결하기 위해 사용한 접근 방식입니다.

    select
        b.id,
        b.code,
        concat_ws('',b.p) as p,
        concat_ws('',b.q) as q,
        concat_ws('',b.r) as r,
        concat_ws('',b.t) as t
    from 
        (
            select id, code,
            collect_list(a.group_map['p']) as p,
            collect_list(a.group_map['q']) as q,
            collect_list(a.group_map['r']) as r,
            collect_list(a.group_map['t']) as t
            from (
                select
                  id,
                  code,
                  map(proc1,proc2) as group_map 
                from 
                  test_sample
            ) a
            group by
                a.id,
                a.code
        ) b;
    

    "concat_ws"와 "map"은 하이브 udf이고 "collect_list"는 하이브 udaf입니다.

  2. ==============================

    2.여기 내가 사용을 끝내 솔루션입니다 :

    여기 내가 사용을 끝내 솔루션입니다 :

    add jar brickhouse-0.7.0-SNAPSHOT.jar;
    CREATE TEMPORARY FUNCTION collect AS 'brickhouse.udf.collect.CollectUDAF';
    
    select 
        id, 
        code,
        group_map['p'] as p,
        group_map['q'] as q,
        group_map['r'] as r,
        group_map['t'] as t
        from ( select
            id, code,
            collect(proc1,proc2) as group_map 
            from test_sample 
            group by id, code
        ) gm;
    

    to_map UDF는 brickhouse repo에서 사용되었습니다. https://github.com/klout/brickhouse

  3. ==============================

    3.또 다른 해결책.

    또 다른 해결책.

    Hivemall to_map 함수를 사용하여 피벗합니다.

    SELECT
      uid,
      kv['c1'] AS c1,
      kv['c2'] AS c2,
      kv['c3'] AS c3
    FROM (
      SELECT uid, to_map(key, value) kv
      FROM vtable
      GROUP BY uid
    ) t
    

    uid c1 c2 c3 101 11 12 13 102 21 22 23

    피 피 보트 해제

    SELECT t1.uid, t2.key, t2.value
    FROM htable t1
    LATERAL VIEW explode (map(
      'c1', c1,
      'c2', c2,
      'c3', c3
    )) t2 as key, value
    

    uid 키 값 101 c1 11 101 c2 12 101 c3 13 102 c1 21 102 c2 22 102 c3 23

  4. ==============================

    4.이 코드는 작성하지 않았지만 klouts brickhouse에서 제공하는 UDF를 사용할 수 있다고 생각합니다. https://github.com/klout/brickhouse

    이 코드는 작성하지 않았지만 klouts brickhouse에서 제공하는 UDF를 사용할 수 있다고 생각합니다. https://github.com/klout/brickhouse

    특히, 여기에 언급 된 것처럼 수집을 사용하는 것과 같은 것을 할 수 있습니다. http://brickhouseconfessions.wordpress.com/2013/03/05/use-collect-to-avoid-the-self-join/

    그런 다음이 게시물에 설명 된 방법을 사용하여 배열을 분해합니다 (길이가 다를 수 있습니다). http://brickhouseconfessions.wordpress.com/2013/03/07/exploding-multiple-arrays-at-the-same-time- with-numeric_ra

  5. ==============================

    5.숫자 값의 경우 아래 하이브 쿼리를 사용할 수 있습니다.

    숫자 값의 경우 아래 하이브 쿼리를 사용할 수 있습니다.

    샘플 데이터

    ID  cust_freq   Var1    Var2    frequency
    220444  1   16443   87128   72.10140547
    312554  6   984 7339    0.342452643
    220444  3   6201    87128   9.258396518
    220444  6   47779   87128   2.831972441
    312554  1   6055    7339    82.15209213
    312554  3   12868   7339    4.478333954
    220444  2   6705    87128   15.80822558
    312554  2   37432   7339    13.02712127
    
    select id, sum(a.group_map[1]) as One, sum(a.group_map[2]) as Two, sum(a.group_map[3]) as Three, sum(a.group_map[6]) as Six from
    ( select id, 
     map(cust_freq,frequency) as group_map 
     from table
     ) a group by a.id having id in 
    ( '220444',
    '312554');
    
    ID  one two three   six
    220444  72.10140547 15.80822558 9.258396518 2.831972441
    312554  82.15209213 13.02712127 4.478333954 0.342452643
    
    In above example I have't used any custom udf. It is only using in-built hive functions.
    Note :For string value in key write the vale as sum(a.group_map['1']) as One.
    
  6. ==============================

    6.Unpivot의 경우 아래 논리를 사용하면됩니다.

    Unpivot의 경우 아래 논리를 사용하면됩니다.

    SELECT Cost.Code, Cost.Product, Cost.Size
    , Cost.State_code, Cost.Promo_date, Cost.Cost, Sales.Price
    FROM
    (Select Code, Product, Size, State_code, Promo_date, Price as Cost
    FROM Product
    Where Description = 'Cost') Cost
    JOIN
    (Select Code, Product, Size, State_code, Promo_date, Price as Price
    FROM Product
    Where Description = 'Sales') Sales
    on (Cost.Code = Sales.Code
    and Cost.Promo_date = Sales.Promo_date);
    
  7. ==============================

    7.아래는 피벗 (Pivot)을위한 방법입니다.

    아래는 피벗 (Pivot)을위한 방법입니다.

    SELECT TM1_Code, Product, Size, State_code, Description
      , Promo_date
      , Price
    FROM (
    SELECT TM1_Code, Product, Size, State_code, Description
       , MAP('FY2018Jan', FY2018Jan, 'FY2018Feb', FY2018Feb, 'FY2018Mar', FY2018Mar, 'FY2018Apr', FY2018Apr
            ,'FY2018May', FY2018May, 'FY2018Jun', FY2018Jun, 'FY2018Jul', FY2018Jul, 'FY2018Aug', FY2018Aug
            ,'FY2018Sep', FY2018Sep, 'FY2018Oct', FY2018Oct, 'FY2018Nov', FY2018Nov, 'FY2018Dec', FY2018Dec) AS tmp_column
    FROM CS_ME_Spirits_30012018) TmpTbl
    LATERAL VIEW EXPLODE(tmp_column) exptbl AS Promo_date, Price;
    
  8. ==============================

    8.case 문과 collect_set의 도움을 받아이를 수행 할 수 있습니다. 이것을 확인할 수 있습니다. 자세한 내용은 http://www.analyticshut.com/big-data/hive/pivot-rows-to-columns-in-hive/에서 확인할 수 있습니다.

    case 문과 collect_set의 도움을 받아이를 수행 할 수 있습니다. 이것을 확인할 수 있습니다. 자세한 내용은 http://www.analyticshut.com/big-data/hive/pivot-rows-to-columns-in-hive/에서 확인할 수 있습니다.

    다음은 참조 용 쿼리입니다.

    SELECT resource_id,
    CASE WHEN COLLECT_SET(quarter_1)[0] IS NULL THEN 0 ELSE COLLECT_SET(quarter_1)[0] END AS quarter_1_spends,
    CASE WHEN COLLECT_SET(quarter_2)[0] IS NULL THEN 0 ELSE COLLECT_SET(quarter_2)[0] END AS quarter_2_spends,
    CASE WHEN COLLECT_SET(quarter_3)[0] IS NULL THEN 0 ELSE COLLECT_SET(quarter_3)[0] END AS quarter_3_spends,
    CASE WHEN COLLECT_SET(quarter_4)[0] IS NULL THEN 0 ELSE COLLECT_SET(quarter_4)[0] END AS quarter_4_spends
    FROM (
    SELECT resource_id,
    CASE WHEN quarter='Q1' THEN amount END AS quarter_1,
    CASE WHEN quarter='Q2' THEN amount END AS quarter_2,
    CASE WHEN quarter='Q3' THEN amount END AS quarter_3,
    CASE WHEN quarter='Q4' THEN amount END AS quarter_4
    FROM billing_info)tbl1
    GROUP BY resource_id;
    
  9. from https://stackoverflow.com/questions/23025380/how-to-transpose-pivot-data-in-hive by cc-by-sa and MIT license