How to split queried data by delimiter in Oracle?

假装没事ソ 提交于 2021-01-28 05:13:24

问题


I have following row A1,A2,A3;A4,A5,A6 And I want to query this data as 2 rows: A1,A2,A3 and A4,A5,A6

Below query returns multiple rows of 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
;

回答1:


You can do it using a recursive sub-query factoring clause and simple string functions (rather than slow regular expressions).

(Note: this also does not have the issues hierarchical queries do when there are multiple input rows of it generating exponentially more output rows at each depth as it cannot correlate each row with its parent so it will correlate it with all rows at the prior hierarchy level.)

Oracle Setup:

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;

Query:

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;

Output:

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<>fiddle here




回答2:


Based on MT0's sample data (thank you, MT0!), here's how to avoid duplicate rows.

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>


来源:https://stackoverflow.com/questions/57756272/how-to-split-queried-data-by-delimiter-in-oracle

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!