[英]Search pattern and remove search string characters if not found and then search it again in oracle sql
I have to write a query which is having a where clause like below: 我必须编写一个查询,其中包含如下所示的where子句:
select x from table where col1 like '%6789%';
Now the requirement I have is if above query doesn't return anything then search with 678 or 789 or 67 or 89. 现在我的要求是,如果上面的查询不返回任何内容,则使用678或789或67或89搜索。
How can I achieve this in best optimised way? 如何以最佳的方式实现这一目标?
Search once for any value containing 6, 7, 8 or 9, order by how well the value matches '6789'
and take the top result. 一次搜索包含6、7、8或9的任何值,并按该值与
'6789'
匹配程度排序,并获得最高的结果。
(Edit: I've added an instr
expression to prioritise occurrences of the exact string '6789'
over the JW score, as otherwise '678 blah'
would rank higher than 'blah 6789'
.) (编辑:我添加了一个
instr
表达式以将确切字符串'6789'
出现优先于JW分数,否则'678 blah'
排名将高于'blah 6789'
。)
create table demo (col1) as
( select column_value
from table(sys.dbms_debug_vc2coll
( '6789','678X','X789','67XX','XX89','XXXX','6XXX','X7XX','11111167891111'
, '167891','Germany 6, England 7 what a great match that was in 1989')) );
select col1
, utl_match.jaro_winkler_similarity(col1,'6789') as match_rating
, nullif(instr(col1,'6789'),0) as match_position
from demo
where regexp_like(col1,'[6789]')
order by match_position nulls last, match_rating desc;
COL1 MATCH_RATING MATCH_POSITION
-------------------------------------------------------- ------------ --------------
6789 100 1
167891 88 2
11111167891111 59 7
678X 88
X789 83
67XX 73
XX89 66
6XXX 55
X7XX 50
Germany 6, England 7 what a great match that was in 1989 34
10 rows selected
Filter to get the first row (Oracle 12.1 onwards): 过滤以获取第一行(从Oracle 12.1开始):
select col1
from demo
where regexp_like(col1,'[6789]')
order by
nullif(instr(col1,'6789'),0) nulls last
, utl_match.jaro_winkler_similarity(col1,'6789') desc
fetch first row only;
COL1
-----
6789
For older versions: 对于旧版本:
select col1
from ( select col1
from demo
where regexp_like(col1,'[6789]')
order by
nullif(instr(col1, '6789'),0) nulls last
, utl_match.jaro_winkler_similarity(col1,'6789') desc )
where rownum = 1;
http://sqlfiddle.com/#!4/a9d884/3 http://sqlfiddle.com/#!4/a9d884/3
Note '6789'
can be replaced with a variable in PL/SQL: 注意
'6789'
可以用PL / SQL中的变量替换:
select col1 into :result
from demo
where regexp_like(col1,'['||p_pattern||']')
order by
nullif(instr(col1, p_pattern),0) nulls last
, utl_match.jaro_winkler_similarity(col1,p_pattern) desc
fetch first row only;
You can achieve executing different select with order using UNION ALL combined with NOT EXISTS , similar to this answer 您可以使用UNION ALL结合NOT EXISTS来实现按顺序执行不同的选择,类似于此答案
select x from table where col1 like '%6789%'
UNION ALL
select x from table where col1 like '%678%' or col1 like '%789%'
or col1 like '%67%' or col1 like '%89%'
AND NOT EXISTS (
select x from table where col1 like '%6789%'
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.