如何在Oracle中使用substr/instr拆分字符串

qaxu7uf2  于 2023-03-29  发布在  Oracle
关注(0)|答案(2)|浏览(152)

大家早上好,我正在尝试将一个字符串从Oracle表中的一列拆分为多列,方法是在字符串中找到一个特定的单词,然后返回该单词后面的值。我正在寻找的条件中的单词将始终相同,但可能不总是在相同的位置。
我的表中的列名叫做Criteria下面是一个我试图拆分的字符串的示例:
| 标准|
| --------------|
| [SampleNum:'3230',SampleState:“就绪”,收集原因:“强制”,操作:'提交']|
因此,任务是将Criteria解析为SampleNum、SampleState、Action和CollectionReason列
我希望我的结果看起来像下面这样:
| 样本NUm|样品状态|收集原因|
| --------------|--------------|--------------|
| 小行星3230|准备|强制性|
我已经尝试了一些事情,如以下,我找到每个逗号之间的数据,但这只是没有帮助,因为我真的试图找到一个特定的词,然后检索该词之后和逗号之前的数据。
这是我到目前为止提出的,但再次,不完全是我要找的。
任何帮助将不胜感激,以找出如何找到一个特定的词,然后得到该词后的值。提前感谢

SELECT
   criteria,INSTR(criteria,',',1,1) AS first_comma,
   INSTR(criteria,',',1,2) AS second_comma,
   INSTR(criteria,',',1,3) AS third_comma
   ,INSTR(criteria,',',1,4) AS fourth_comma,
   INSTR(criteria,',',1,5) AS fifth_comma
   ,SUBSTR(criteria
             ,INSTR(criteria,',',1,1) + 1
             ,INSTR(criteria,',',1,2)
              - INSTR(criteria,',',1,1)
              - 1)
       AS column2
         ,SUBSTR(criteria
             ,INSTR(criteria,',',1,2) + 1
             ,INSTR(criteria,',',1,3)
              - INSTR(criteria,',',1,2)
              - 1)
       AS column3       
                ,SUBSTR(criteria
             ,INSTR(criteria,',',1,3) + 1
             ,INSTR(criteria,',',1,4)
              - INSTR(criteria,',',1,3)
              - 1)
       AS column4  
                       ,SUBSTR(criteria
             ,INSTR(criteria,',',1,4) + 1
             ,INSTR(criteria,',',1,5)
              - INSTR(criteria,',',1,4)
              - 1)
       AS column5       
              FROM
    table1
h7wcgrx3

h7wcgrx31#

您可以尝试以下查询

SELECT 
    REGEXP_SUBSTR(criteria, 'SampleNum:\s*''(.*?)''', 1, 1, NULL, 1) AS SampleNum
  , REGEXP_SUBSTR(criteria, 'SampleState:\s*''(.*?)''', 1, 1, NULL, 1) AS SampleState
  , REGEXP_SUBSTR(criteria, 'CollectionReason:\s*''(.*?)''', 1, 1, NULL, 1) AS CollectionReason  
FROM 
  table1

参见here演示

yftpprvb

yftpprvb2#

您可以找到引号的位置,然后使用它来查找子字符串:

SELECT SUBSTR(criteria, q1 + 1, q2 - q1 - 1) AS samplenum,
       SUBSTR(criteria, q3 + 1, q4 - q3 - 1) AS samplestate,
       SUBSTR(criteria, q5 + 1, q6 - q5 - 1) AS collectionreason
FROM   (
  SELECT criteria,
         INSTR(criteria, '''', 1, 1) AS q1,
         INSTR(criteria, '''', 1, 2) AS q2,
         INSTR(criteria, '''', 1, 3) AS q3,
         INSTR(criteria, '''', 1, 4) AS q4,
         INSTR(criteria, '''', 1, 5) AS q5,
         INSTR(criteria, '''', 1, 6) AS q6
  FROM   table1
);

正则表达式比简单的字符串函数慢;在这种情况下,它们使您从哪里获取数据以及预期的格式变得非常明显,因此从开发/维护的Angular 来看,这可能是值得的:

SELECT REGEXP_SUBSTR(
         criteria,
         '^\[SampleNum: ''(.*?)'', SampleState: ''(.*?)'', CollectionReason: ''(.*?)'', Action: ''(.*?)''\]$',
         1,
         1,
         NULL,
         1
       ) AS samplenum,
       REGEXP_SUBSTR(
         criteria,
         '^\[SampleNum: ''(.*?)'', SampleState: ''(.*?)'', CollectionReason: ''(.*?)'', Action: ''(.*?)''\]$',
         1,
         1,
         NULL,
         2
       ) AS samplestate,
       REGEXP_SUBSTR(
         criteria,
         '^\[SampleNum: ''(.*?)'', SampleState: ''(.*?)'', CollectionReason: ''(.*?)'', Action: ''(.*?)''\]$',
         1,
         1,
         NULL,
         3
       ) AS collectionreason
FROM   table1

其中,对于示例数据:

CREATE TABLE table1 (criteria) AS
SELECT '[SampleNum: ''3230'', SampleState: ''Ready'', CollectionReason: ''Mandatory'', Action: ''Submit'']' FROM DUAL;

两个输出:
| 样品|样品状态|收集原因|
| --------------|--------------|--------------|
| 小行星3230|准备|强制性|
fiddle

相关问题