我有一个名为“ 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
答案 0 :(得分: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.
答案 1 :(得分:0)
如果您想对多行使用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;