暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 然后将字符串解析为列

askTom 2018-09-13
533

问题描述

嗨,

表单不接受LiveSQL链接:
https://livesql.oracle.com/apex/livesql/s/g88hb5van1r4ctc65yp4lq9gb

我有这种情况 (见链接):

ID String
Id1 Thing1: Sub1,
Thing2: Sub7,Sub8,Sub9
Thing3: Sub12
Id1 Thing2: Sub6,Sub7,Sub8,
Thing3: Sub12,Sub13
Id1 Thing1: Sub1,Sub2
Thing2: Sub7,Sub8,Sub9
Thing3: Sub12
Id2 Thing1: Sub2,Sub3
Thing2: Sub7
Thing3: Sub13
Id3事物2: Sub7

所以每个Id可以有多个字符串,这些字符串包含两个级别的信息。我想将字符串分成两列,以便记录处于 'level2' 级别,这看起来像这样:

ID Level1 Level2
Id1 Thing1 Sub1
Id1 Thing2 Sub7
Id1 Thing2 Sub8
Id1 Thing2 Sub9
Id1 Thing3 Sub12
Id1 Thing2 Sub6
Id1 Thing2 Sub7
Id1 Thing2 Sub8
Id1 Thing3 Sub12
Id1 Thing3 Sub13
Id1 Thing1 Sub1
Id1 Thing1 Sub2
Id1 Thing2 Sub7
Id1 Thing2 Sub8
Id1 Thing2 Sub9
Id1 Thing3 Sub12
Id2 Thing1 Sub2
Id2 Thing1 Sub3
Id2 Thing2 Sub7
Id2 Thing3 Sub13
Id3 Thing2 Sub7

在将两个级别解析为逗号分隔的子字符串之后,我实际上已经使用此语法 (两次) 工作了:

regexp_substr(table_name,'[^,]+', 1, level) AS level1_flat,
connect by regexp_substr(table_name, '[^,]+', 1, level) is not null


但是在大型数据集上工作太慢了。我不完全理解上面的代码,我想它正在做一个交叉连接,我正在应用一个不同的选择来忽略欺骗,但这显然是无效的。

任何帮助将不胜感激。

谢谢,
鲁特格


专家解答

这不是交叉连接。

但是对于每一行,你正在构建完整的树:

-它的字符串分成行
-每隔一行的字符串拆分为行!

因此,对于第1行,您将其他四行中的每一行都链接为一个子。然后,对于这四个中的每一个,创建下面剩下的三个树。等等。

所以对于每一行,你创建一个有89行的树。5倍。

这导致行数爆炸。随着你的表有更多的行,这呈指数级增长。

通过确保仅添加链接到原始父级的子行来避免这种情况。您可以通过以下方式执行此操作:

-使用连接通过内部横向子查询 (需要12.1)

select id, regexp_substr(string,'[^,]+', 1, x) AS level1_flat 
from   test, lateral (
  select level x from dual 
  connect by regexp_substr(string, '[^,]+', 1, level) is not null
);


-检查先前的字符串是否与当前字符串相同

select id,
       regexp_substr(string,'[^,]+', 1, level) AS level1_flat
from   test
connect by regexp_substr(string, '[^,]+', 1, level) is not null
and     string = prior string
and     prior sys_guid() is not null; -- avoid loops


如果这仍然不够快,你可以尝试使用xmltable与标记操作:

select id, str 
from   test, xmltable(
    'if (contains($X,",")) then ora:tokenize($X,"\,") else $X'
  passing string as X
  columns str varchar2(4000) path '.'
);


最后,您可以为substr/instr切换正则表达式。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论