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.
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;
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;
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).
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.