oracle 需要从键值对数据中提取值

dpiehjr4  于 2023-11-17  发布在  Oracle
关注(0)|答案(2)|浏览(177)

我有一列包含键值对中的值,但我只需要从该列中提取值。
输入表:

+------+---------------------------------+
| Col1 |              Col2               |
+------+---------------------------------+
|    1 | key1:Val1;Key2:Val2;;;Key5:Val5 |
+------+---------------------------------+

字符串
预期输出:

+------+--------------------------------+------+------+------+------+
| Col1 |              Col2              | Col3 | Col4 | Col5 | Col6 |
+------+--------------------------------+------+------+------+------+
|    1 | key1:Val1;Key2:Val2;;Key4:Val4 | Val1 | Val2 |      | Val4 |
+------+--------------------------------+------+------+------+------+


说明:
由于Col2包含键值对中的值,因此我只需要提取value并将其存储在不同的列中,并且在没有值的地方我们需要将其置为空。因此,基本上,需要识别;:
我的尝试:

SELECT
  Col1,
  SUBSTR(REGEXP_SUBSTR(Col1, 'Key1:(.*?)(;|$)', 1, 1, NULL, 1), 5) AS Col2
From table_name;

DB - Oracle Sql Developer tool
Version - 19c


我不知道这是否是处理这一要求的最佳方式,因此寻求帮助。

piztneat

piztneat1#

您使用的技术基本上是正确的,但存在一些小问题:
1.你没有将模式锚到一个词的开头,所以如果你有数据kkey1:not this;key1:this,你搜索key1,那么你将部分匹配kkey1键,得到错误的值。
1.您的数据混合了标题和小写键,并且您只搜索标题大小写键名称。
1.目前还不清楚为什么要使用SUBSTR,因为您是从正则表达式中提取捕获组,而不是整个匹配,因此您不需要删除键前缀。
如果你想对表进行UPDATE(即将其存储在不同的列中),那么用途:

UPDATE table_name
  SET col3 = REGEXP_SUBSTR(Col2, '(;|^)key1:(.*?)(;|$)', 1, 1, 'i', 2),
      col4 = REGEXP_SUBSTR(Col2, '(;|^)key2:(.*?)(;|$)', 1, 1, 'i', 2),
      col5 = REGEXP_SUBSTR(Col2, '(;|^)key3:(.*?)(;|$)', 1, 1, 'i', 2),
      col6 = REGEXP_SUBSTR(Col2, '(;|^)key4:(.*?)(;|$)', 1, 1, 'i', 2),
      col7 = REGEXP_SUBSTR(Col2, '(;|^)key5:(.*?)(;|$)', 1, 1, 'i', 2)

字符串
对于示例数据:

CREATE TABLE table_name (
  col1 VARCHAR2(20),
  col2 VARCHAR2(100),
  col3 VARCHAR2(20),
  col4 VARCHAR2(20),
  col5 VARCHAR2(20),
  col6 VARCHAR2(20),
  col7 VARCHAR2(20)
);

INSERT INTO table_name (col1, col2)
  VALUES (1, 'key1:Val1;Key2:Val2;;;Key5:Val5');


然后,在UPDATE之后,该表包含:
| COL1| COL2| COL3| COL4| COL5| COL6| Col7|
| --|--|--|--|--|--|--|
| 1 |key1:Val1;Key2:Val2;Key5:Val5| Val1| Val2| * 空 | 空 *| Val5|
如果你只是想要一个SELECT语句,那么使用与SELECT中的UPDATE相同的REGEXP_SUBSTR函数调用:

SELECT col1,
       col2,
       REGEXP_SUBSTR(Col2, '(;|^)key1:(.*?)(;|$)', 1, 1, 'i', 2) AS col3,
       REGEXP_SUBSTR(Col2, '(;|^)key2:(.*?)(;|$)', 1, 1, 'i', 2) AS col4,
       REGEXP_SUBSTR(Col2, '(;|^)key3:(.*?)(;|$)', 1, 1, 'i', 2) AS col5,
       REGEXP_SUBSTR(Col2, '(;|^)key4:(.*?)(;|$)', 1, 1, 'i', 2) AS col6,
       REGEXP_SUBSTR(Col2, '(;|^)key5:(.*?)(;|$)', 1, 1, 'i', 2) AS col7
FROM  table_name;


fiddle

7kqas0il

7kqas0il2#

这里有一种方法,使用JSON_TABLE将分隔列拆分为行,然后应用REGEXP_REPLACE从键值对中提取值:

SELECT COL1, 
       COL2,
       MAX(CASE WHEN ID = 3 THEN REGEXP_REPLACE(ELEMENT, '^.*:', '') END) COL3,
       MAX(CASE WHEN ID = 4 THEN REGEXP_REPLACE(ELEMENT, '^.*:', '') END) COL4,
       MAX(CASE WHEN ID = 5 THEN REGEXP_REPLACE(ELEMENT, '^.*:', '') END) COL5,
       MAX(CASE WHEN ID = 6 THEN REGEXP_REPLACE(ELEMENT, '^.*:', '') END) COL6,
       MAX(CASE WHEN ID = 7 THEN REGEXP_REPLACE(ELEMENT, '^.*:', '') END) COL7
FROM (
  SELECT COL1, COL2, 2+ID AS ID, ELEMENT
  FROM mytable t
  CROSS JOIN JSON_TABLE( '["' || REPLACE(col2, ';', '","') || '"]'  , '$[*]'
                COLUMNS (
                      ID FOR ORDINALITY,
                      ELEMENT VARCHAR2(20) PATH '$')
               ) j
) s
GROUP BY COL1, COL2

字符串
Demo here

相关问题