我正在尝试从表中创建一个视图,该视图将多列中的逗号分隔值转换为Oracle中的行。
我已成功完成了一个专栏。但我不能用两三列来做。
我使用了以下脚本成功运行一列。
Create VIEW MULTITESET AS
SELECT rownum AS ID1,Tagging.COMMENTS,Tagging.category,Tagging.STATUS,
trim(regexp_substr(Tagging.OBJ_ID, '[^,]+', 1, lines.column_value)) OBJ_ID
FROM Tagging,
TABLE (CAST (MULTISET
(SELECT LEVEL FROM dual
CONNECT BY instr(Tagging.OBJ_ID, ',', 1, LEVEL - 1) > 0
) AS sys.odciNumberList ) ) lines
ORDER BY id, lines.column_value
现在我需要对名为OBJname
的第二列执行相同的操作,就像列OBJ_ID
一样。
所以我尝试了一些愚蠢的东西,如下所示,这是行不通的。
Create VIEW MULTITESET AS
SELECT rownum AS ID1,Tagging.COMMENTS,Tagging.category,Tagging.STATUS,
trim(regexp_substr(Tagging.OBJ_ID, '[^,]+', 1, lines.column_value)) OBJ_ID
FROM Tagging,
TABLE (CAST (MULTISET
(SELECT LEVEL FROM dual
CONNECT BY instr(Tagging.OBJ_ID, ',', 1, LEVEL - 1) > 0
) AS sys.odciNumberList ) ) lines
ORDER BY id, lines.column_value ,
trim(regexp_substr(Tagging.OBJname , '[^,]+', 1, lines.column_value)) OBJname
FROM Tagging,
TABLE (CAST (MULTISET
(SELECT LEVEL FROM dual
CONNECT BY instr(Tagging.OBJname , ',', 1, LEVEL - 1) > 0
) AS sys.odciNumberList ) ) lines
ORDER BY id, lines.column_value
在坚果壳中,我希望下图中的tabel-A转换为表-B。我怎么能这样做?
我的实际查看查询是:
SELECT rownum AS TRACKID2, LEAPFROG_TAGGING.ID, LEAPFROG_TAGGING.CREATED_DATE,
LEAPFROG_TAGGING.CREATED_BY, LEAPFROG_TAGGING.COMMENTS,
leapfrog_tagging.category, LEAPFROG_TAGGING.STATUS, LEAPFROG_TAGGING.OBJ_NAME,
trim(regexp_substr(LEAPFROG_TAGGING.OBJ_ID, '[^,]+', 1, lines.column_value)) OBJ_ID
FROM LEAPFROG_TAGGING,
TABLE (CAST (MULTISET (
SELECT LEVEL FROM dual
CONNECT BY instr(LEAPFROG_TAGGING.OBJ_ID, ',', 1, LEVEL - 1) > 0
) AS sys.odciNumberList ) ) lines
ORDER BY id, lines.column_value;
答案 0 :(得分:1)
假设逗号分隔值的数量总是在两列中匹配(每个ID只有一个名称),并且您使用的是11gR2,则可以使用recursive subquery factoring:
create view multiteset as
with t (obj_id, obj_name, status, other_columns, rn, orig_obj_id, orig_obj_name) as (
select regexp_substr(obj_id, '[^,]+', 1, 1),
regexp_substr(obj_name, '[^,]+', 1, 1),
status, other_columns, 1, obj_id, obj_name
from tagging
union all
select regexp_substr(orig_obj_id, '[^,]+', 1, rn + 1),
regexp_substr(orig_obj_name, '[^,]+', 1, rn + 1),
status, other_columns, rn + 1, orig_obj_id, orig_obj_name
from t
where rn < regexp_count(orig_obj_id, '[^,]+')
)
select obj_id, obj_name, status, other_columns
from t;
select * from multiteset;
OBJ_ID OBJ_NAME STATUS OTHER_
---------------------------- -------- ------ ------
1 a open value1
1 a closed value2
4 hj na value3
2 s open value1
2 s closed value2
5 hj na value3
3 d open value1
6 hj na value3
4 f open value1
7 hj na value3
10 rows selected.
您的问题中的列名称有点不一致,因此您必须调整您的真实姓名。
锚成员从每个列表中获取第一个元素,并保留原始列表的副本,以及一个计数器,以查看我们所在的元素(从1开始)。
递归成员然后在每个列表中查找下一个(rn +
)元素,除了计数器之外,将其余值保持不变。
针对CTE的最终查询然后只获取生成的值,忽略CTE跟踪的临时值(rn
,orig_obj_id
等。)
您在评论中添加的新原始视图定义可能真的需要:
create view multiteset as
with t (id, created_date, created_by, comments, category, status,
obj_name, obj_id, rn, orig_obj_name, orig_obj_id)
as (
select id, created_date, created_by, comments, category, status,
regexp_substr(obj_name, '[^,]+', 1, 1),
regexp_substr(obj_id, '[^,]+', 1, 1),
1, obj_name, obj_id
from leapfrog_tagging
union all
select id, created_date, created_by, comments, category, status,
regexp_substr(orig_obj_name, '[^,]+', 1, rn + 1),
regexp_substr(orig_obj_id, '[^,]+', 1, rn + 1),
rn + 1, orig_obj_name, orig_obj_id
from t
where rn < regexp_count(orig_obj_id, '[^,]+')
)
select id, created_date, created_by, comments, category, status,
obj_name, obj_id
from t;
另请注意,没有order by
条款;在视图定义中没有意义,并且应该在查询视图时应用:
select * from multiteset order by id, obj_id;
如果你想保留位置标记,那么也可以按顺序排列视图结果,然后在最终选择列表中包含rn
(或更有意义的名字!),例如:
...
select id, rn as trackid2, created_date, created_by, comments, category, status,
obj_name, obj_id
from t;
可以让你:
select * from multiteset order by id, trackid2;