oracle 从字符串中提取值

cfh9epnr  于 2022-12-22  发布在  Oracle
关注(0)|答案(3)|浏览(223)

我有一个列,我需要为它提取R值。
做这件事的最好方法是什么?
我觉得我已经接近目标,但在获取所需内容方面存在问题
基本上需要R值,可以是不同字符长,直到控制实验室.
参见以下示例。

select SUBSTR( err_desc, 57, INSTR (err_desc, 'Control Lab:', 1, 1)-1)
from error_log
where sql_err_text = 'EXCEEDED VARIANCE LIMIT'
and year = '2022';

例如:

Plant: 649 Order: 2HC2204018 Year: 2022 Cycle: 01  Raw: R-66-59-18 Control Lab: WH Variance Warning: 50 Variance Limit: 100

所需输出:第一个月

Plant: 650 Order: 9GM2202004 Year: 2022 Cycle: 03  Raw: R-401059 Control Lab: GR

所需输出:R-401059
已尝试上面的SQL。获得的字符数超出预期。

osh3o9ms

osh3o9ms1#

我将REGEXP_SUBSTR()与捕获组一起使用:

SELECT err_desc, REGEXP_SUBSTR(err_desc, 'Raw: (R(-[0-9]+)+)', 1, 1, NULL, 1) AS output
FROM error_log
WHERE sql_err_text = 'EXCEEDED VARIANCE LIMIT' AND year = '2022';
rekjcdws

rekjcdws2#

如果您只需要第一个键值对中以Raw结尾的键值,则可以使用:

SELECT id,
       CASE
       WHEN spos = 0 THEN NULL
       WHEN epos = 0 THEN SUBSTR(value, spos + 6)
       ELSE               SUBSTR(value, spos + 6, epos - spos - 6)
       END AS raw_value
FROM   (
  SELECT id,
         ' ' || value AS value,
         INSTR(' ' || value, ' Raw: ') AS spos,
         INSTR(' ' || value, ' ', INSTR(' ' || value, ' Raw: ') + 6) AS epos
  FROM   table_name
)

或者,键入较少,但执行正则表达式要慢得多:

SELECT id,
       REGEXP_SUBSTR(value, '(^| )Raw: (\S+)', 1, 1, NULL, 2) AS raw_value
FROM   table_name;

其中,对于示例数据:

CREATE TABLE table_name ( id, value ) AS
SELECT 1, 'Plant: 649 Order: 2HC2204018 Year: 2022 Cycle: 01  Raw: R-66-59-18 Control Lab: WH Variance Warning: 50 Variance Limit: 100' FROM DUAL UNION ALL
SELECT 2, 'Plant: 650 Order: 9GM2202004 Year: 2022 Cycle: 03  Raw: R-401059 Control Lab: GR' FROM DUAL UNION ALL
SELECT 3, 'Plant: 651 Not Raw: NOT-THIS Raw: XYZ-123' FROM DUAL;

两个输出:
| 识别号|原始值|
| - ------| - ------|
| 1个|R-66 - 59 - 18|
| 第二章|R-401059|
| 三个|非本品|

  • 注意:如果你有多个以Raw结尾的键-值对,那么这个(以及其他人的答案)会搞不清你想要哪个键,并返回第一个匹配Raw的键。*

如果你想要所有的键-值对(假设你使用:来分隔键-值对,并且每个值在下一个空格字符之后结束),那么你可以使用:

WITH bounds (id, value, spos, delim_pos, epos) AS (
  SELECT id,
         value,
         1,
         INSTR(value, ': ', 1),
         INSTR(value, ' ', INSTR(value, ': ', 1) + 2)
  FROM   table_name
UNION ALL
  SELECT id,
         value,
         epos + 1,
         INSTR(value, ': ', epos + 1),
         INSTR(value, ' ', INSTR(value, ': ', epos + 1) + 2)
  FROM   bounds
  WHERE  epos > 0
) SEARCH DEPTH FIRST BY id SET order_id,
SELECT id,
       TRIM(SUBSTR(value, spos, delim_pos - spos)) AS key,
       CASE epos
       WHEN 0
       THEN SUBSTR(value, delim_pos + 2)
       ELSE SUBSTR(value, delim_pos + 2, epos - delim_pos - 2)
       END AS value
FROM   bounds;

对于样本数据,它输出:
| 识别号|关键词|价值|
| - ------| - ------| - ------|
| 1个|植物|六百四十九|
| 1个|订单|2HC2204018|
| 1个|年份|小行星2022|
| 1个|周期|一|
| 1个|原始|R-66 - 59 - 18|
| 1个|控制实验室|白度|
| 1个|差异警告|五十|
| 1个|差异限度|一百|
| 第二章|植物|六百五十|
| 第二章|订单|9GM220二○ ○四|
| 第二章|年份|小行星2022|
| 第二章|周期|03|
| 第二章|原始|R-401059|
| 第二章|控制实验室|自然伽马|
| 三个|植物|六五一|
| 三个|非原始|非本品|
| 三个|原始|XYZ-123|
如果在获取所有键后只需要Raw值,则可以使用过滤器:

WITH bounds (id, value, spos, delim_pos, epos) AS (
  SELECT id,
         value,
         1,
         INSTR(value, ': ', 1),
         INSTR(value, ' ', INSTR(value, ': ', 1) + 2)
  FROM   table_name
UNION ALL
  SELECT id,
         value,
         epos + 1,
         INSTR(value, ': ', epos + 1),
         INSTR(value, ' ', INSTR(value, ': ', epos + 1) + 2)
  FROM   bounds
  WHERE  epos > 0
) SEARCH DEPTH FIRST BY id SET order_id,
key_value_pairs (id, key, value) AS (
  SELECT id,
         TRIM(SUBSTR(value, spos, delim_pos - spos)),
         CASE epos
         WHEN 0
         THEN SUBSTR(value, delim_pos + 2)
         ELSE SUBSTR(value, delim_pos + 2, epos - delim_pos - 2)
         END
  FROM   bounds
)
SELECT *
FROM   key_value_pairs
WHERE  key = 'Raw';

其输出:
| 识别号|关键词|价值|
| - ------| - ------| - ------|
| 1个|原始|R-66 - 59 - 18|
| 第二章|原始|R-401059|
| 三个|原始|XYZ-123|
如果在Raw中有多个结尾,它将获得正确的密钥。
fiddle

rjjhvcjd

rjjhvcjd3#

具有substr + instr组合的选项;你必须找到Raw开始的位置,然后减去ControlRaw位置(找到子串长度)。+5(以及-5)代表“原始”,冒号和空格。+1在这里正确设置子串长度。

SQL> with error_log (err_desc) as
  2    (select 'Plant: 649 Order: 2HC2204018 Year: 2022 Cycle: 01  Raw: R-66-59-18 Control Lab: WH Variance Warning: 50 Variance Limit: 100' from dual union all
  3     select 'Plant: 650 Order: 9GM2202004 Year: 2022 Cycle: 03  Raw: R-401059 Control Lab: GR' from dual
  4    )
  5  select substr(err_desc, instr(err_desc, 'Raw') + 5,
  6                          instr(err_desc, 'Control') - instr(err_desc, 'Raw') - 5 + 1
  7               ) result
  8  from error_log;

RESULT
--------------------------------------------------------------------------------
R-66-59-18 C
R-401059 C

SQL>

相关问题