regexp_substr在foward斜杠之前恢复数据

时间:2018-04-16 10:37:57

标签: sql oracle regexp-substr

我在数据集中有以下字符模式。我需要操纵数据和交叉将它引用到另一个表。我正在尝试编写一个regexp_substr,以便在从左侧开始执行斜线之前恢复数据。例如: -

abc/ab/123/zzz

所以我需要得到以下结果然后与另一个表

进行比较
abc
abc/ab
abc/ab/123

我已经解决了其他逻辑,但是正在与各种正则表达式进行斗争。

2 个答案:

答案 0 :(得分:1)

您不需要正则表达式。您可以使用(更快的)字符串函数来完成它:

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE test_data ( id, value ) AS
  SELECT 1, 'abc/ab/123/zzz' FROM DUAL;

查询1

WITH bounds ( id, value, end_pos ) AS (
  SELECT id,
         value,
         INSTR( value, '/', 1 )
  FROM   test_data
  WHERE  INSTR( value, '/', 1 ) > 0
UNION ALL
  SELECT id,
         value,
         INSTR( value, '/', end_pos + 1 )
  FROM   bounds
  WHERE  INSTR( value, '/', end_pos + 1 ) > 0
)
SELECT id,
       SUBSTR( value, 1, end_pos ) AS item
FROM   bounds
ORDER BY id, end_pos

<强> Results

| ID |        ITEM |
|----|-------------|
|  1 |        abc/ |
|  1 |     abc/ab/ |
|  1 | abc/ab/123/ |

但是,如果你确实想使用正则表达式,那么你可以这样做:

查询2

WITH bounds ( id, value, lvl, item ) AS (
  SELECT id,
         value,
         1,
         REGEXP_SUBSTR( value, '.*?/', 1, 1 )
  FROM   test_data
  WHERE  REGEXP_SUBSTR( value, '.*?/', 1, 1 ) IS NOT NULL
UNION ALL
  SELECT id,
         value,
         lvl + 1,
         item || REGEXP_SUBSTR( value, '.*?/', 1, lvl + 1 )
  FROM   bounds
  WHERE  REGEXP_SUBSTR( value, '.*?/', 1, lvl + 1 ) IS NOT NULL
)
SELECT id,
       item
FROM   bounds

<强> Results

| ID |        ITEM |
|----|-------------|
|  1 |        abc/ |
|  1 |     abc/ab/ |
|  1 | abc/ab/123/ |

答案 1 :(得分:1)

以下是SUBSTRINSTR的递归查询:

with cte(col) as
(
  select substr(col, 1, instr(col, '/', -1) - 1) from mytable
  union all
  select substr(col, 1, instr(col, '/', -1) - 1) from cte where instr(col, '/') > 0
)
select col from cte;

以下是REGEXP_REPLACE的查询:

with cte(col) as
(
  select regexp_replace(col, '/[^/]*$', '') from mytable
  union all
  select regexp_replace(col, '/[^/]*$', '') from cte where instr(col, '/') > 0
)
select col from cte;