【问题标题】:Splitting every row of varchar column and create new row for every split part拆分 varchar 列的每一行并为每个拆分部分创建新行
【发布时间】:2018-11-27 12:51:33
【问题描述】:

我有一个名为“Table”的表和名为“History”的属性。这个历史属性的值如下:

   1 Finished (30-05-2018);
   2 InProgress (25-05-2018); Rejected(26-05-2018); InProgress (28-05-2018); Finished (30-05-2018);
   3 InProgress (25-05-2018); Finished (30-05-2018);

我想用分号 (;) 分割这个属性,并为每个历史部分创建一个新行。因此,对于上面代码/示例中的行,它应该创建 7 行。我已经通过下面的代码成功地做到了这一点。问题是我想为此表中的每一行执行此操作。这里出现了一个问题:当我删除 WITH 中的 WHERE 条件时,我得到了许多结果行以及许多 NULL 值。我究竟做错了什么?

WITH DATA AS
   ( SELECT "WorkID" w,"History" his FROM Table
   where "WorkID" = 75671
   )
   SELECT w, trim(regexp_substr(his, '[^;]+', 1, LEVEL)) his
   FROM DATA
   CONNECT BY regexp_substr(his , '[^;]+', 1, LEVEL) IS NOT NULL

【问题讨论】:

    标签: sql oracle split common-table-expression


    【解决方案1】:

    这是一个完整的工作示例,其中正则表达式查找分号的分隔符,后跟空格或行尾:

    SQL> WITH Tbl(WorkID, History) AS(
         select 1, 'Finished (30-05-2018);' from dual union all
         select 2, 'InProgress (25-05-2018); Rejected(26-05-2018); InProgress (28-05-2018); Finished (30-05-2018);' from dual union all
         select 3, 'InProgress (25-05-2018); Finished (30-05-2018);' from dual
       )
       select WorkID, regexp_substr(History, '(.*?)(; |;$)', 1, level, NULL, 1) history
       from Tbl
       connect by regexp_substr(History, '(.*?)(; |;$)', 1, level) is not null
       and prior WorkID = WorkID
       and prior sys_guid() is not null;
    
        WORKID HISTORY
    ---------- -------------------------
             1 Finished (30-05-2018)
             2 InProgress (25-05-2018)
             2 Rejected(26-05-2018)
             2 InProgress (28-05-2018)
             2 Finished (30-05-2018)
             3 InProgress (25-05-2018)
             3 Finished (30-05-2018)
    
    7 rows selected.
    

    【讨论】:

      【解决方案2】:

      如果你想对多行使用connect by 将一列拆分为多行,你需要做一些额外的事情——告诉 Oracle 循环遍历同一行,并进行检查确保它知道要使用哪一行。

      这意味着您的查询将变为:

      select "WorkID" w,
             "History" his
      from table
      connect by prior "WorkID" = "WorkID" -- I'm assuming that "WorkID" uniquely identifies a row; if not, add in the additional columns that identify a row
      and regexp_substr("History", '[^;]+', 1, level) is not null
      and prior sys_guid() is not null;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多