想象一下我有一张像
Name
----
ABCDEFG
ABChello world
ABCDEfoo
ABbar
ABCDEF
ABCDEFGHIJKLMNOP
zzz
qABCD
ABCqqqGH
ABCABC
我想做一个查询并找出每个字符串有多少个字符与所需的字符串“ABCDEFGHIJ”匹配,总是从头开始。那是...
Name MatchingLength
---- ----
ABCDEFG 7
ABChello world 3
ABCDEzoo 5
ABbar 2
ABCDEF 6
ABCDEFGHIJKLMNOP 10
zzz 0
qABCD 0
ABCqqqGH 3
ABCABC 3
有什么办法可以在 Oracle 中干净利落地做到这一点?我不知所措。
最佳答案
不知道“干净”,但这里有两个解决方案。
-- The hardcoded, bad performance. No transformation of your string though.
with patterns as (
select substr('ABCDEFGHIJ', 1, rownum) txt
from dual
connect by level <= length('ABCDEFGHIJ')
)
select d.txt, coalesce(max(length(p.txt)), 0)
from dummy d
left join patterns p
on instr(d.txt, p.txt) = 1
group by d.txt
order by 2 desc;
-- The cool one with regex.
-- Though transforming your input string,
-- this can also be done with ease making something that transorms it for you
-- like in the previous example, more complicated task than the previous,
-- as oracle sucks with string manipulation. You can however write it in java.
select d.txt, coalesce(LENGTH(REGEXP_SUBSTR(d.txt, '^A(B(C(D(E(F(G(H(I(J)?)?)?)?)?)?)?)?)')), 0)
from dummy d;
http://www.sqlfiddle.com/#!4/85ba6/23
更新
with patterns as (
select substr('ABCDEFGHIJ', 1, rownum) txt
from dual
connect by level <= length('ABCDEFGHIJ')
)
select d.txt, coalesce(max(length(p.txt)), 0)
from dummy d
left join patterns p
on instr(d.txt, p.txt) = 1
where d.txt LIKE substr('ABCDEFGHIJ', 1, 1) || '%'
group by d.txt
order by 2 desc;
更新 fiddle :http://www.sqlfiddle.com/#!4/37400/6
在 oracle 10g 上测试生成的查询计划
SELECT STATEMENT, GOAL = ALL_ROWS
SORT ORDER BY
SORT GROUP BY NOSORT
NESTED LOOPS OUTER
INDEX RANGE SCAN I <<<< Uses the index.
VIEW
COUNT
CONNECT BY WITHOUT FILTERING
FAST DUAL
关于string - Oracle:获取部分字符串匹配的长度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15538454/