SQL将由|分隔的字符串解析为键和值

SQL将由|分隔的字符串解析为键和值,sql,parsing,hive,split,hiveql,Sql,Parsing,Hive,Split,Hiveql,我需要关于解析由管道分隔的字符串的帮助。第一个数字是键,管道后的后续字符串是该键的数百个值 |01|00109394|05|84|08|34353637 这应该分为三个部分 第一根管道后长度为2的键 值:在每个键之后 第一个键=01,值=00,10,93,94 第二个键=05,值=84 等等 脚本应该打断字符串并分解为行,这样列“key”将包含所有键,“values”列将包含所有值 样本输出 KEY Value 01 00 01 10 01 93 01 94 05 84 08

我需要关于解析由管道分隔的字符串的帮助。第一个数字是键,管道后的后续字符串是该键的数百个值

|01|00109394|05|84|08|34353637
这应该分为三个部分 第一根管道后长度为2的键 值:在每个键之后

  • 第一个键=01,值=00,10,93,94
  • 第二个键=05,值=84
  • 等等
脚本应该打断字符串并分解为行,这样列“key”将包含所有键,“values”列将包含所有值

样本输出

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;

请建议如何解析此字符串

我使用了拆分和分解两次。第一次获取未拆分的键和值,第二次使用两个字符分隔值。阅读代码中的注释:

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!=''
;

我用分裂和爆炸两次。第一次获取未拆分的键和值,第二次使用两个字符分隔值。阅读代码中的注释:

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!=''
;

什么是DBMS是什么,什么是“不工作”的意思?也可以考虑修复该模式,并从一开始就以标准化的方式存储数据。应该有一个表,其中一列表示键,另一列表示值,如果顺序在这里很重要,可能还有一列表示序数。每个值在该表中应有一行。查询将从配置单元获取数据。我无法修复模式,因为它是作为日志收集的数据,必须这样保存。它不起作用,因为它通过管道拆分字符串,将整个字符串转换为“值”。我需要它以一种方式拆分,它读取“键”,然后将后续值作为键的“值”。然后它应该读取第二个键并放入下一行。我不知道当键和值都由相同的管道分隔符“|”分隔时,如何从字符串中提取键。您使用的是哪种产品?“SQL”只是一种查询语言,而不是特定数据库产品的名称。什么是DBMS是什么,什么是“不工作”的意思?也可以考虑修复该模式,并从一开始就以标准化的方式存储数据。应该有一个表,其中一列表示键,另一列表示值,如果顺序在这里很重要,可能还有一列表示序数。每个值在该表中应有一行。查询将从配置单元获取数据。我无法修复模式,因为它是作为日志收集的数据,必须这样保存。它不起作用,因为它通过管道拆分字符串,将整个字符串转换为“值”。我需要它以一种方式拆分,它读取“键”,然后将后续值作为键的“值”。然后它应该读取第二个键并放入下一行。我不知道当键和值都由相同的管道分隔符“|”分隔时,如何从字符串中提取键。您使用的是哪种产品?“SQL”只是一种查询语言,而不是特定数据库产品的名称。