web-dev-qa-db-fra.com

Hive Explode/Lateral View plusieurs tableaux

J'ai une table Hive avec le schéma suivant: 

COOKIE  | PRODUCT_ID | CAT_ID |    QTY    
1234123   [1,2,3]    [r,t,null]  [2,1,null]

Comment puis-je normaliser les tableaux afin d'obtenir le résultat suivant 

COOKIE  | PRODUCT_ID | CAT_ID |    QTY

1234123   [1]          [r]         [2]

1234123   [2]          [t]         [1] 

1234123   [3]          null       null 

J'ai essayé ce qui suit: 

select concat_ws('|',visid_high,visid_low) as cookie
,pid
,catid 
,qty
from table
lateral view explode(productid) ptable as pid
lateral view explode(catalogId) ptable2 as catid 
lateral view explode(qty) ptable3 as qty

cependant, le résultat est un produit cartésien.

12
user2726995

Vous pouvez utiliser les fichiers UDF numeric_range et array_index de Brickhouse ( http://github.com/klout/brickhouse ) pour résoudre ce problème. Un blog informatif décrit en détail à http://brickhouseconfessions.wordpress.com/2013/03/07/exploding-multiple-arrays-at-the-same-time-with-numeric_range/

En utilisant ces fonctions UDF, la requête ressemblerait à quelque chose comme: 

select cookie,
   array_index( product_id_arr, n ) as product_id,
   array_index( catalog_id_arr, n ) as catalog_id,
   array_index( qty_id_arr, n ) as qty
from table
lateral view numeric_range( size( product_id_arr )) n1 as n;
15
Jerome Banks

J'ai trouvé une très bonne solution à ce problème sans utiliser de fichier UDF, posexplode est une très bonne solution:

SELECT COOKIE, 
 EPRODUCT_ID, 
 ECAT_ID, 
 EQTY 
 DE LA TABLE 
 LATERAL VIEW posexplode (PRODUCT_ID) ePRODUCT_IDAS seqp, ePRODUCT_ID 
 LATERAL VIEW posexplode (CAT_ID eCAT_ID) __. VUE LATÉRALE posexplode (QTY) eQTY AS seqq, eDateReported 
 WHERE seqp = seqc ET seqc = seqq;
11
ahmed abdellatif

Vous pouvez le faire en utilisant posexplode, qui fournira un entier compris entre 0 et n pour indiquer la position dans le tableau pour chaque élément du tableau. Ensuite, utilisez cet entier - appelez-le pos (pour position) pour obtenir les valeurs correspondantes dans d'autres tableaux, en utilisant la notation de bloc, comme ceci: 

select 
  cookie, 
  n.pos as position, 
  n.prd_id as product_id,
  cat_id[pos] as catalog_id,
  qty[pos] as qty
from table
lateral view posexplode(product_id_arr) n as pos, prd_id;

Cela évite d’utiliser des fichiers UDF importés et d’assembler plusieurs tableaux (ce qui donne de bien meilleures performances). 

0
dataMD

J'ai essayé de travailler sur votre scénario ... s'il vous plaît essayez ce code - 

create table info(cookie string,productid int,catid string,qty string);

insert into table info
select cookie,productid[myprod],categoryid[mycat],qty[myqty] from table
lateral view posexplode(productid) pro as myprod,pro
lateral view posexplode(categoryid) cate as mycat,cate
lateral view posexplode(qty) q as myqty,q
where myprod=mycat and mycat=myqty;

Remarque - Dans les instructions ci-dessus, placez -select cookie,myprod,mycat,myqty from table à la place de select cookie,productid[myprod],categoryid[mycat],qty[myqty] from table dans la sortie, vous obtiendrez l'index de l'élément dans les tableaux productid, categoryid et qty. J'espère que cela vous sera utile.

0