/ Align = "left" /

Mam tabelę ula z następującym schematem:

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

Jak mogę znormalizować tablice, aby uzyskać następujący wynik

COOKIE  | PRODUCT_ID | CAT_ID |    QTY

1234123   [1]          [r]         [2]

1234123   [2]          [t]         [1] 

1234123   [3]          null       null 

Próbowałem:

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

Jednak wynik wychodzi jako iloczyn kartezjański.

Author: Jean-François Corbett, 2013-12-19

4 answers

Możesz użyć numeric_range i array_index UDFs z Brickhouse ( http://github.com/klout/brickhouse ), aby rozwiązać ten problem. Jest pouczający blog opisujący szczegółowo w http://brickhouseconfessions.wordpress.com/2013/03/07/exploding-multiple-arrays-at-the-same-time-with-numeric_range/{[5]

Używając tych UDFs, zapytanie byłoby czymś w rodzaju

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;
 14
Author: Jerome Banks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-23 18:21:17

Znalazłem bardzo dobre rozwiązanie tego problemu bez użycia UDF, posexplode jest bardzo dobrym rozwiązaniem:

SELECT COOKIE ,
ePRODUCT_ID,
eCAT_ID,
eQTY
FROM TABLE 
LATERAL VIEW posexplode(PRODUCT_ID) ePRODUCT_IDAS seqp, ePRODUCT_ID
LATERAL VIEW posexplode(CAT_ID) eCAT_ID AS seqc, eCAT_ID
LATERAL VIEW posexplode(QTY) eQTY AS seqq, eDateReported
WHERE seqp = seqc AND seqc = seqq;
 11
Author: ahmed abdellatif,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-15 16:22:27

Można to zrobić za pomocą posexplode, który dostarczy liczbę całkowitą między 0 a n, aby wskazać pozycję w tablicy dla każdego elementu w tablicy. Następnie użyj tej liczby całkowitej-nazwij ją pos (dla pozycji), aby uzyskać pasujące wartości w innych tablicach, używając notacji blokowej, jak to:

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;

Pozwala to uniknąć używania importowanych UDF oraz łączenia różnych tablic ze sobą (ma to znacznie lepszą wydajność).

 0
Author: dataMD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-22 11:28:58

Próbowałem wypracować twój scenariusz... proszę wypróbować ten kod -

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;

Uwaga-w powyższych wypowiedziach, jeśli umieścisz - select cookie,myprod,mycat,myqty from table w miejsce select cookie,productid[myprod],categoryid[mycat],qty[myqty] from table w wyjściu otrzymasz indeks elementu w tablicy productid, categoryid i qty. Mam nadzieję, że to będzie pomocne.

 0
Author: Lakshman Purihella,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-26 06:48:36