我有这个查询:
select regexp_substr('1,2,3,4,5','[^,]+',1,level)
from test1
connect by instr('1,2,3,4,5',',',1,level-1)>0;
请帮助我理解此查询,尤其是一个级别的用法,以及by和level-1的连接。
答案 0 :(得分:0)
LEVEL和CONNECT BY用于生成序列,请参见以下简单示例:
select level
from dual
connect by level < 10;
LEVEL
=======
1
2
3
4
5
6
7
8
9
instr('1,2,3,4,5', ',' , 1, level-1) > 0
计算用逗号分隔的元素的数量,也许此版本更易于理解,其作用相同:
select regexp_substr('1,2,3,4,5','[^,]+',1,level)
from dual
connect by LEVEL <= REGEXP_COUNT('1,2,3,4,5', ',')+1;
LEVEL <= REGEXP_COUNT('1,2,3,4,5', ',')+1
或instr('1,2,3,4,5', ',' , 1, level-1) > 0
表示“运行5次”。
因此,您的选择基本上是
的快捷方式select regexp_substr('1,2,3,4,5','[^,]+', 1, 1) from dual union all
select regexp_substr('1,2,3,4,5','[^,]+', 1, 2) from dual union all
select regexp_substr('1,2,3,4,5','[^,]+', 1, 3) from dual union all
select regexp_substr('1,2,3,4,5','[^,]+', 1, 4) from dual union all
select regexp_substr('1,2,3,4,5','[^,]+', 1, 5) from dual;
答案 1 :(得分:0)
@Wernfried的回答很好,但是您应该知道'[^,]+'
格式的正则表达式存在很大的风险,人们经常将其视为解析分隔字符串的示例。
仅当存在列表的所有元素时,此选项才有效。为了让您大开眼界,请尝试将第二个元素设为NULL:
select regexp_substr('1,,3,4,5', '[^,]+', 1, 3) from dual;
REGEXP_SUBSTR('1,,3,4,5','[^,]+',1,3)
-------------------------------------
4
1 row selected.
什么? '4'
绝对是该列表的第3个元素,不!如您所见,没有处理NULL。
请使用以下格式的REGEXP_SUBSTR
来处理NULL列表元素:
select regexp_substr('1,,3,4,5','(.*?)(,|$)', 1, 3, NULL, 1) from dual;
REGEXP_SUBSTR('1,,3,4,5','(.*?)(,|$)',1,3,NULL,1)
-------------------------------------------------
3
1 row selected.
正则表达式定义了2组,一组可选的任何字符,后跟逗号或行尾。 REGEXP_SUBSTR的参数 说返回此比赛的第三个实例的第一组。