如何让 REGEXP_LIKE 先得到确切的词,然后再附加所有相关的词?

How to get REGEXP_LIKE that gets the exact word first, then append all the word related later?

Table 描述:

id   desc
0    ball
1    basketball
2    ballpen
3    a ball
4    ball pen

table 期望输出

id    desc  
 0    ball  
 3    a ball  
 4    ball pen  
 2    ballpen  
 1   basketball

连顺序都不一样。 但重要的是,我首先要得到确切的词,然后是所有相关的词。 a ball 仍然被认为是准确的词,所以它可以是第一个。

我宁愿建议这样的东西,而不是正则表达式:UTL_MATCH

SQL> with test (id, c_desc) as
  2  (select 0, 'ball'       from dual union
  3   select 1, 'basketball' from dual union
  4   select 2, 'ballpen'    from dual union
  5   select 3, 'a ball'     from dual union
  6   select 4, 'ball pen'   from dual union
  7   select 5, 'littlefoot' from dual
  8  )
  9  select
 10    id,
 11    c_desc,
 12    utl_match.jaro_winkler_similarity (c_desc, '&&par_desc') similarity
 13  from test
 14  where instr(c_desc, '&&par_desc') > 0
 15  order by utl_match.jaro_winkler_similarity (c_desc, '&&par_desc') desc;
Enter value for par_desc: ball

        ID C_DESC     SIMILARITY
---------- ---------- ----------
         0 ball              100
         2 ballpen            91
         4 ball pen           89
         3 a ball             80
         1 basketball         65

SQL> undefine par_desc
SQL> /
Enter value for par_desc: pinky

no rows selected

SQL> undefine par_desc
SQL> /
Enter value for par_desc: tle

        ID C_DESC     SIMILARITY
---------- ---------- ----------
         5 littlefoot         65

SQL>

这里有两种方法 return 所有带有独立词 "ball" 的行,然后是包含 "ball" 的那些在另一个词中的行。

首先,如果您想确保只有 "ball" 的行首先出现,请在您的排序中构建一个 case 表达式。

在此检查该值是否等于您的搜索变量。如果它确实映射到一个数字,例如一个。如果它没有映射到更高的数字,例如二.

对于return所有包含ball的行,这里有两种方式:

regexp_like

您可以使用正则表达式:

(^|\s|\W)球($|\s|\W)

在 SQL 中看起来像:

create table t as 
  select 0 id, 'ball' val from dual union
  select 1, 'basketball' from dual union
  select 2, 'ballpen'    from dual union
  select 3, 'a ball'     from dual union
  select 4, 'ball pen'   from dual union
  select 5, 'littlefoot' from dual;

var v varchar2(10);

exec :v := 'ball';

select * 
from   t
where  val like '%' || :v || '%'
order  by case 
  when val = :v then 1
  when regexp_like ( val, '(^|\s|\W)' || :v || '($|\s|\W)' ) then 2
  else 3
end, id;

ID   VAL          
   0 ball         
   3 a ball       
   4 ball pen     
   1 basketball   
   2 ballpen 

Oracle 文本

如果在列上创建 Oracle Text 索引,则可以使用 contains 来查找匹配的行。调用两次。一次找到完全匹配。然后再次显示与单词的匹配。

然后按照分数从高到低排序。先是准确分数,再是其他:

create index test_i on t ( val ) indextype is ctxsys.context;

select t.*, score (1), score (2) from t
where  contains ( val, :v, 1 ) > 0
or     contains ( val, '%' || :v || '%', 2 ) > 0
order  by case 
  when val = :v then 1
  else 2
end, score ( 1 ) desc, score ( 2 ) desc;

ID   VAL          SCORE(1)   SCORE(2)   
   0 ball                  4          4 
   3 a ball                4          4 
   4 ball pen              4          4 
   1 basketball            0          4 
   2 ballpen               0          4