SQL /如何根据特定列中的分号char获取多个记录

时间:2018-01-29 20:18:09

标签: sql oracle subquery oracle12c substr

我想知道如何在不使用任何功能的情况下解决这个问题。我在我正在处理的应用程序中有一些嵌入式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

任何帮助表示感谢。

2 个答案:

答案 0 :(得分:1)

这是一个选项:

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>

答案 1 :(得分:0)

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

hive> select * FROM products_test;
OK
Failed with exception java.io.IOException:org.apache.hadoop.hive.serde2.SerDeException: java.io.IOException: Field name expected

答案?

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;