Мне нужна помощь в разборе строк, которые разделены трубкой. первое число является ключом, а последующая строка после трубы - значения для этого ключа в сотнях

|01|00109394|05|84|08|34353637

это должно быть разбито на ключи, которые имеют длину = 2 после первых значений канала: после каждого ключа

  • first_key = 01, значения = 00, 10, 93, 94
  • second_key = 05, значения = 84
  • скоро...

скрипт должен разбивать строку и разбиваться на строки, чтобы в столбце «ключ» были все ключи, в столбце «значения» были все все значения

образец вывода

KEY Value
01  00
01  10
01  93
01  94
05  84
08  34
08  35

Вот код, который я написал, но не работает

Select my_key, explode(str_to_map(my_key,'[|]','[|]')) as (Key, Value)
from test_table;

Подскажите пожалуйста как разобрать эту строку

1
Samy 19 Дек 2019 в 21:56

1 ответ

Лучший ответ

Я сделал это с помощью раскола и взрыва два раза. Первый раз, чтобы получить ключ и значение не разделены и второй раз, чтобы разделить значения на два символа. Прочитайте комментарии в коде:

with your_data as (
select stack (1, '|01|00109394|05|84|08|34353637') as str
)

select --s.initial_str, 
       s.key, v.val
from
(
select s.pos, s.initial_str, s.key, s.val
from
(
select s.initial_str,
       s.pos, --0 and even positions are keys, odd are values
       s.val as key, 
       --assign the value to each key, which is the next eploded value 
       lead(val,1) over(partition by s.initial_str order by s.pos) as val --some keys from main table are in partition by clause
from       
( --explode string
select d.str initial_str, s.pos, s.val
  from your_data d lateral view outer posexplode(split(regexp_replace(str,'(^\\|)|(\\|$)',''),'\\|')) s as pos, val --remove leading and trailing pipe and explode
) s
)s
where s.pos%2=0 --filter keys with assigned values only (0 and even are rows we need)
) s 
--explode each two chars
--(?<=\\G.{2}) matches an empty string that has the last match (\\G) followed by two characters (.{2}) before it (?<=)
lateral view outer explode(split(s.val,'(?<=\\G.{2})')) v as val 
where v.val!=''
;

Результат:

01      00
01      10
01      93
01      94
05      84
08      34
08      35
08      36
08      37
0
leftjoin 20 Дек 2019 в 07:08