3

抽取样本表:

WITH t(val) AS
     ( SELECT 'my Name' FROM dual
     UNION
     SELECT 'my name' FROM dual
     UNION
     SELECT 'my naim' FROM dual
     UNION
     SELECT 'MY kat' FROM dual
     UNION
     select 'my katt' from dual
    )
SELECT * FROM t;

我需要一个优先输出:

查询应首先在表中搜索完全匹配,如果未找到则按 搜索lowering the case,如果未找到则仅搜索soundex,。所以最终输出类似于:

WHERE val = 'my Name'
  OR lower(val) = lower('my Name')
  OR soundex(lower(val)) = soundex(lower('my Name'))

应该:

output
-----
my Name

提前致谢。

4

4 回答 4

1

只需按照您的描述进行过滤,然后按该顺序排序,然后获取第一条记录:

WITH t AS
     ( SELECT 'my Name' as val FROM dual
     UNION
     SELECT 'my name' FROM dual
     UNION
     SELECT 'my naim' FROM dual
     UNION
     SELECT 'MY kat' FROM dual
     UNION
     select 'my katt' from dual
    )
SELECT * FROM
(
  SELECT * FROM t
  WHERE val = 'my Name'
  OR lower(val) = lower('my Name')
  OR soundex(lower(val)) = soundex(lower('my Name'))
  order by
    case 
      when val = 'my Name' then 1
      when lower(val) = lower('my Name') then 2
      when soundex(lower(val)) = soundex(lower('my Name')) then 3
    end
)
WHERE ROWNUM = 1;
于 2013-10-29T12:00:21.307 回答
1

对于大型数据集,如果任何较早的数据集找到匹配项,您可能希望避免不必要的测试。

with t as
   ( SELECT 'my Name' as val FROM dual
   UNION
   SELECT 'my name' FROM dual
   UNION
   SELECT 'my naim' FROM dual
   UNION
   SELECT 'MY kat' FROM dual
   UNION
   select 'my katt' from dual
    )
  exact_match as (
    select *
    from   t
    where  val = 'my Name'),
  lower_case_match as (
    select *
    from   t
    where  lower(val) = lower('my Name') and
           not exists (select null from exact_match)),
  soundex_match as (
    select *
    from   t
    where  soundex(val) = soundex('my Name') and
           not exists (select null from lower_case_match) and
           not exists (select null from exact_match))
select * from exact_match
union all
select * from lower_case_match
union all
select * from soundex_match;

Oracle 很可能会具体化前两个搜索公用表表达式的结果集,以便使后续表达式更有效地测试它们是否返回结果。如果第一个“exact_match”搜索返回结果,则不需要执行后续搜索。

于 2013-11-29T15:04:33.750 回答
0

可能您需要 oracle 文本,更准确地说是查询松弛:http ://docs.oracle.com/cd/B28359_01/text.111/b28303/query.htm#i1007593

你可以模仿类似的东西:

select
 *
from
 (select *,
   case
      when condition1 then 3
      when condition2 then 2
      when condition3 then 1
   end relevance
  from
    table
  where
    (condition1 or condition2 or condition3)
  )
order by
  relevance desc
于 2013-10-29T10:59:41.627 回答
0

我的呢:(感谢@Thorsten Kettner)。

SELECT val FROM(
  SELECT val, DENSE_RANK()OVER(ORDER BY CASE WHEN val = 'my Name' THEN 1
                                             WHEN lower(val) = lower('my Name') THEN 2
                                             WHEN soundex(lower(val)) = soundex(lower('my Name')) THEN 3
                                        END
                               )rnk
  FROM t
  WHERE val = 'my Name'
  OR lower(val) = lower('my Name')
  OR soundex(lower(val)) = soundex(lower('my Name'))
)
WHERE rnk  = 1; 

Oracle 特别为我们的目的而设计的另一个FIRST

SELECT MAX(val) keep (dense_rank FIRST ORDER BY priority) AS val
FROM
     (SELECT t.* ,
          CASE WHEN val = 'my Name' THEN 1
               WHEN lower(val) = lower('my Name') THEN 2
               WHEN soundex(lower(val)) = soundex(lower('my Name')) THEN 3
          END priority
     FROM t
     WHERE val                = 'my Name'
       OR lower(val)          = lower('my Name')
       OR soundex(lower(val)) = soundex(lower('my Name'))
     );
于 2013-10-30T03:19:21.857 回答