I do not know about the "clean", but there are two solutions.
-- 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
UPDATE
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;
Updated script: http://www.sqlfiddle.com/#!4/37400/6
Request plan prepared on 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
source share