【问题标题】:Parse value delimited from both sides of it into multiple rows将从其两侧分隔的值解析为多行
【发布时间】:2019-09-03 13:24:09
【问题描述】:

我有一个这样的列值

#123##456##789#*0123*, (每个值都在两边解析),我想把它解析成这样:

id value type
1 123     #
1 456     #
1 789     #
1 0123    *

我该怎么做?

额外问题,我想在查询中传递 id,解析器应该知道它应该解析的列(我不想解析静态值),该查询的外观如何像。提前致谢!

【问题讨论】:

  • 您是否可以使用除 Oracle 之外的任何其他工具?这是一个数据清理问题,而数据库并不是执行此操作的最佳位置。
  • 好吧,我应该写一个脚本,用基于该列的值填充一个表,我应该在 oracle sql 中完成所有操作。
  • 如果你真的想在Oracle中做这个,你可能需要写一个存储过程。
  • 这些值是否只有数字?而且,总是*# 中的类型?第二个问题我不是很清楚,你能发布一些示例数据和需要的结果吗?
  • 查看这个相关问题以获得关于这类一般问题的一些好的答案。 stackoverflow.com/questions/38371989/…

标签: sql oracle plsql oracle11g split


【解决方案1】:

好的,我修改了MT0's recursive CTE answer from the link above 以处理两个分隔符(即,在两端),并将分隔符拉出到单独的列中。如果您有任何问题,请告诉我。

with example as (select 1 as id, '#123##456##789#*0123*' as str from dual
                union select 2, '#837#*827*#3021#*013*' from dual),
  t ( id, str, start_pos, end_pos ) AS
    ( SELECT id, str, 1, REGEXP_INSTR( str, '[^0-9]' ) FROM example
    UNION ALL
    SELECT id,
      str,
      end_pos                    + 1,
      REGEXP_INSTR( str, '[^0-9]', end_pos + 1 )
    FROM t
    WHERE end_pos > 0
    )
SELECT id, 
  --str, start_pos, end_pos, -- uncomment for debugging
  SUBSTR( str, start_pos, DECODE( end_pos, 0, LENGTH( str ) + 1, end_pos ) - start_pos ) AS value,
  substr(str, start_pos-1, 1) as type
FROM t
where start_pos <> end_pos and end_pos <> 0
  -- bonus question - uncomment to filter by ID
  --and id = 1
ORDER BY id,
  start_pos;

仅供参考 - 这将删除空值(例如“##”)并且不会将它们显示为一行。

【讨论】:

  • 非常感谢,你做到了我的要求,甚至更多!
猜你喜欢
  • 2012-10-11
  • 2020-01-20
  • 1970-01-01
  • 1970-01-01
  • 2017-07-17
  • 1970-01-01
  • 2012-06-16
  • 2021-11-04
  • 1970-01-01
相关资源
最近更新 更多