SQL / 如何根据特定列中的分号字符获取多条记录

SQL / How to get multiple records based on a semicolon char in a particular column

我想知道如何在不使用任何函数的情况下解决这个问题。我在我正在处理的应用程序中有某种嵌入式 SQL 客户端 (12c),因此我无法在查询之外使用函数和过程。

我有这样的输入: ID ¦ APP 14 ¦ AAA;BBBB;CC 15 ¦ AAA;DDDDD 16 ¦ BBBB;CC 17 ¦ AAA;BBBB;CC;DDDDD

我想动态转换成这样: ID ¦ APP 14 ¦ AAA 14 ¦ BBBB 14 ¦ CC 15 ¦ AAA 15 ¦ DDDDD 16 ¦ BBBB 16 ¦ CC 17 ¦ AAA 17 ¦ BBBB 17 ¦ CC 17 ¦ DDDDD

感谢任何帮助。

这是一种选择:

SQL> with test (id, app) as
  2  (select 14, 'aaa;bbb;cc' from dual union
  3   select 15, 'aaa;dddd'   from dual union
  4   select 16, 'bbbb;cc'    from dual
  5  )
  6  select id, regexp_substr(app, '[^;]+', 1, column_value) app
  7  from test,
  8       table(cast(multiset(select level from dual
  9                           connect by level <= regexp_count(app, ';') + 1)
 10                           as sys.odcinumberlist))
 11  order by 1, 2;

        ID APP
---------- ----------------------------------------
        14 aaa
        14 bbb
        14 cc
        15 aaa
        15 dddd
        16 bbbb
        16 cc

7 rows selected.

SQL>

Littlefoot 的回答被接受为答案,但我喜欢使用常见的 table 表达式,所以我开发了一个使用 CTE 的解决方案。此解决方案可用于非 Oracle 平台:

WITH
    test_dataset (id, app)
    AS
        (SELECT 14 AS id, 'aaa;bbb;cc' AS app
           FROM DUAL
         UNION
         SELECT 15, 'aaa;dddd'
           FROM DUAL
         UNION
         SELECT 16, 'bbbb;cc'
           FROM DUAL
         UNION
         SELECT 17, 'ZZZZ'
           FROM DUAL),
    aset (id, app, extra)
    AS
        (SELECT id
              , CASE WHEN INSTR (app, ';') = 0 THEN app ELSE SUBSTR (app, 1, INSTR (app, ';') - 1) END AS app
              , CASE WHEN INSTR (app, ';') = 0 THEN NULL ELSE SUBSTR (app, INSTR (app, ';') + 1) END AS extra
           FROM test_dataset
         UNION ALL
         SELECT id
              , CASE WHEN INSTR (extra, ';') = 0 THEN extra ELSE SUBSTR (extra, 1, INSTR (extra, ';') - 1) END
              , CASE WHEN INSTR (extra, ';') = 0 THEN NULL ELSE SUBSTR (extra, INSTR (extra, ';') + 1) END
           FROM aset
          WHERE extra IS NOT NULL)
  SELECT id, app
    FROM aset
ORDER BY id, app;

答案?

ID APP
14 aaa
14 bbb
14 cc
15 aaa
15 dddd
16 bbbb
16 cc
17 ZZZZ