表包含单列文本类型。 该文本包含一行或多行,其中每行包含一个或多个由短划线创建的部分。 目标是编写一个查询,为每个部分返回一个元组及其起点和终点。
E.g。
'
--- -- -
----
'
不允许使用UDF(用户自定义函数)
如果需要,我们可能会假设表中只有一条记录。
create table t (txt varchar (1000) not null);
insert into t (txt) values
(
'
--- --- --- ---
---------- -
- - -- -- --- ---
----- ---- --- -- -
-------
'
);
*只需要最后2列(section_start / end),其余列用于调试目的。
line_ind section_ind section_length section_start section_end
-------- ----------- -------------- ------------- -----------
1 1 3 2 4
1 2 3 6 8
1 3 3 11 13
1 4 3 17 19
2 1 10 1 10
2 2 1 21 21
3 1 1 2 2
3 2 1 4 4
3 3 2 6 7
3 4 2 9 10
3 5 3 12 14
3 6 3 16 18
4 1 5 7 11
4 2 4 13 16
4 3 3 18 20
4 4 2 22 23
4 5 1 25 25
5 1 7 4 10
答案 0 :(得分:0)
with l
as
(
select line_ind
,line
from table
(
regexp_split_to_table (-1,t.txt,'\r','')
returns (minus_one int,line_ind int,line varchar(1000))
)
as l
)
select l.line_ind
,s.section_ind
,regexp_instr (l.line,'\S+',1,s.section_ind,0) as section_start
,regexp_instr (l.line,'\S+',1,s.section_ind,1) - 1 as section_end
,char_length (s.section) as section_length
from table
(
regexp_split_to_table (l.line_ind,l.line,'\s+','')
returns (line_ind int,section_ind int,section varchar(1000))
)
as s
,l
where l.line_ind =
s.line_ind
order by l.line_ind
,s.section_ind
;
答案 1 :(得分:0)
Oracle
SELECT row_n AS line_ind
,dense_rank() over(PARTITION BY row_n ORDER BY s_beg) AS section_ind
,s_end - s_beg AS section_length
,s_beg - decode(row_n, 0, 0, instr(a,chr(10),1,row_n)) AS section_start
,s_end - decode(row_n, 0, 0, instr(a,chr(10),1,row_n)) -1 AS section_end
FROM (SELECT a
,s_beg
,DECODE(s_end, 0, length(a) + 1, s_end) AS s_end
,length(substr(a, 1, s_beg))
- length(REPLACE(substr(a, 1, s_beg), chr(10))) AS row_n
,lvl
FROM (SELECT txt as a
,DECODE(LEVEL, 1, 0, regexp_instr(txt , '\s|\n', 1, LEVEL - 1)) + 1 AS s_beg
,regexp_instr(txt , '\s|\n', 1, LEVEL) AS s_end
,LEVEL AS lvl
FROM t
CONNECT BY LEVEL <= length(txt ) - length(regexp_replace(txt , '\s|\n')) + 1)
)WHERE s_beg != s_end;
答案 2 :(得分:0)
select regexp_instr (txt,'-+',1,level,0) - instr (txt,chr(10),regexp_instr (txt,'-+',1,level,0) - length (txt) - 1,1) as section_start
,regexp_instr (txt,'-+',1,level,1) - 1 - instr (txt,chr(10),regexp_instr (txt,'-+',1,level,0) - length (txt) - 1,1) as section_end
from t
connect by level <= regexp_count (txt,'-+')
;