在oracle中,我需要在管道分隔列中找到最后两个值。数据如下所示
MyCol
--------
a|b|c|d
e|f
g
h|i|j
k|l|m|n|o
我的输出应该如下
MyCol ColA ColB
----------------------------
a|b|c|d c d
e|f e f
g null g
h|i|j i j
k|l|m|n|o n o
对于两个级别,我可以使用REGEX分割编写一个选择查询,如下所示
SELECT REGEXP_SUBSTR(MyCol, '[^|]+', 1,1),REGEXP_SUBSTR(MyCol, '[^|]+', 1,2)
我如何在多个级别实现此目标。
答案 0 :(得分:1)
管理得出一些东西。输入r = 1表示第一个值,r = 2表示第二个值。
select v
from (select v
,l
,rownum r
from (select v
,l
from (select regexp_substr('A|B|C|D', '[^|]+', 1, level) v
,level l
from dual
connect by regexp_substr('A|B|C|D', '[^|]+', 1, level) is not null)
order by l desc)
where rownum < 3)
where r = 1
由内而外。此查询将列出各个值:
select regexp_substr('A|B|C|D', '[^|]+', 1, level) v
,level l
from dual
connect by regexp_substr('A|B|C|D', '[^|]+', 1, level) is not null
A 1
B 2
C 3
D 4
围绕它的查询会颠倒顺序,所以我们得到:
D 4
C 3
B 2
A 1
然后我们将结果限制为前两行(rownum&lt; 3)并分配新的rownumber(rownum r)
D 1
C 2
所以最后我们可以选择r = 1或r = 2.
答案 1 :(得分:1)
这是一种使用NULL元素的方法。它有点蛮力:
SQL> with tbl(str) as (
select 'a|b|c|d' from dual
union
select 'e|f' from dual
union
select 'g' from dual
union
select 'h|i|j' from dual
union
select 'k|l|m|n|o' from dual
--regexp_substr() args: string, pattern, position, occurance, match_param, subexpr
)
SELECT str,
REGEXP_SUBSTR( str ,
'([^\|]*)(\||$)',
1,
CASE REGEXP_COUNT( str ,'\|')
WHEN 0 THEN NULL -- 1 element only
ELSE REGEXP_COUNT( str ,'\|')
END,
NULL,
1 ) AS ColA,
REGEXP_SUBSTR( str ,
'([^\|]*)(\||$)',
1,
CASE (REGEXP_COUNT( str ,'\|')+1)
WHEN 1 THEN 1-- 1 element only
ELSE (REGEXP_COUNT( str ,'\|')+1)
END,
NULL,
1 ) AS ColB
FROM tbl;
STR COLA COLB
--------- --------- ---------
a|b|c|d c d
e|f e f
g g
h|i|j i j
k|l|m|n|o n o
SQL>
警告:列表中至少需要有一个值。