如何在Oracle中通过定界符拆分查询的数据?

时间:2019-09-02 11:36:58

标签: sql oracle

我有以下一行A1,A2,A3; A4,A5,A6 我想将数据查询为2行:A1,A2,A3和A4,A5,A6

下面的查询返回A1,A2,A3的多行:

select regexp_substr(value, '[^;]+', 1, level)
from some_table 
where some_id = 8
connect by regexp_substr(value, '[^;]+', 1, level) is not null
;

2 个答案:

答案 0 :(得分:2)

您可以使用递归子查询分解子句和简单的字符串函数(而不是慢速的正则表达式)来做到这一点。

(注意:当层次结构查询有多个输入行时,在每个深度生成指数级增加的输出行,因为它无法将每一行与其父级相关联,因此它也将与之相关联,所以这也没有问题上一个层次结构级别的所有行。)

Oracle设置

CREATE TABLE some_table( some_id, value ) AS
  SELECT 8, 'A1,A2,A3;A4,A5,A6' FROM DUAL UNION ALL
  SELECT 8, 'B1,B2,B3;B4,B5,B6' FROM DUAL UNION ALL
  SELECT 8, 'C1,C2,C3;C4,C5,C6' FROM DUAL;

查询

WITH line_start_end ( some_id, value, startidx, endidx ) AS (
  SELECT some_id,
         value,
         1,
         INSTR( value, ';', 1 )
  FROM   some_table
  WHERE  some_id = 8
UNION ALL
  SELECT some_id,
         value,
         endidx + 1,
         INSTR( value, ';', endidx + 1 )
  FROM   line_start_end
  WHERE  endidx > 0
)
SELECT some_id,
       CASE
       WHEN endidx = 0
       THEN SUBSTR( value, startidx )
       ELSE SUBSTR( value, startidx, endidx - startidx )
       END AS value
FROM   line_start_end;

输出

SOME_ID | VALUE   
------: | :-------
      8 | A1,A2,A3
      8 | B1,B2,B3
      8 | C1,C2,C3
      8 | A4,A5,A6
      8 | B4,B5,B6
      8 | C4,C5,C6

db <>提琴here

答案 1 :(得分:1)

根据MT0的示例数据(谢谢,MT0!),这是避免重复行的方法。

SQL> CREATE TABLE some_table( some_id, value ) AS
  2    SELECT 8, 'A1,A2,A3;A4,A5,A6' FROM DUAL UNION ALL
  3    SELECT 8, 'B1,B2,B3;B4,B5,B6' FROM DUAL UNION ALL
  4    SELECT 8, 'C1,C2,C3;C4,C5,C6' FROM DUAL;

Table created.

SQL> select some_id, regexp_substr(value, '[^;]+', 1, column_value) result
  2  from some_table cross join
  3       table(cast(multiset(select level from dual
  4                           connect by level <= regexp_count(value, ';') + 1
  5                          ) as sys.odcinumberlist ));

   SOME_ID RESULT
---------- -----------------
         8 A1,A2,A3
         8 A4,A5,A6
         8 B1,B2,B3
         8 B4,B5,B6
         8 C1,C2,C3
         8 C4,C5,C6

6 rows selected.

SQL>