如果您有一个或多个输入行,则该解决方案将起作用(而如果您向其输入多于一行数据,分层查询将生成呈指数增长的重复行数)。
将日期对转换为 XML,然后使用XMLTABLE 进行转换:
SELECT id,
x.*
FROM test_data t
CROSS JOIN
XMLTABLE(
( LTRIM(
REGEXP_REPLACE(
t.value,
'\|(\d{4}/\d{2}/\d{2})\|(\d{4}/\d{2}/\d{2})',
',<row><start>\1</start><end>\2</end></row>'
),
','
)
)
COLUMNS
start_date DATE PATH '/row/start',
end_date DATE PATH '/row/end'
) x
所以,对于您的测试数据:
CREATE TABLE test_data ( id, value ) AS
SELECT 1, '|2020/04/26|2020/05/02|2020/05/03|2020/05/10' FROM DUAL UNION ALL
SELECT 2, '|2020/06/01|2020/06/02' FROM DUAL
这个输出:
身份证 | START_DATE |结束日期
-: | :--------- | :--------
1 | 20 年 4 月 26 日 | 20 年 5 月 2 日
1 | 20 年 5 月 3 日 | 20 年 5 月 10 日
2 | 01-JUN-20 | 20 年 6 月 2 日
db小提琴here
或者,如果您只有一个输入,您可以成对拆分数据:
SELECT REGEXP_SUBSTR ( :p, '\|(\d{4}/\d{2}/\d{2})\|(\d{4}/\d{2}/\d{2})', 1, level, NULL, 1 ) as start_date,
REGEXP_SUBSTR ( :p, '\|(\d{4}/\d{2}/\d{2})\|(\d{4}/\d{2}/\d{2})', 1, level, NULL, 2 ) as end_date
FROM DUAL
CONNECT BY LEVEL <= REGEXP_COUNT( :p, '\|(\d{4}/\d{2}/\d{2})\|(\d{4}/\d{2}/\d{2})' )
哪些输出:
START_DATE |结束日期
:--------- | :---------
2020/04/26 | 2020/05/02
2020/05/03 | 2020/05/10
db小提琴here
或使用:
SELECT *
FROM XMLTABLE(
( LTRIM(
REGEXP_REPLACE(
:p,
'\|(\d{4}/\d{2}/\d{2})\|(\d{4}/\d{2}/\d{2})',
',<row><start>\1</start><end>\2</end></row>'
),
','
)
)
COLUMNS
start_date DATE PATH '/row/start',
end_date DATE PATH '/row/end'
)
db小提琴here