简体   繁体   English

MySQL Multiple CASE WHEN in WHERE 子句不起作用

[英]MySQL Multiple CASE WHEN in WHERE clause not working

I am trying to optimize the search engine of my wensite.我正在尝试优化我的 wensite 的搜索引擎。 My data base contains phrases.我的数据库包含短语。 @word is defined as varchar and contains a similar phrase to the one which exist in the DB. @word被定义为 varchar 并包含与数据库中存在的短语相似的短语。 I want if the given search phrase matches exactly to the entry in DB the entry will be chosen, if nothing could be found, search with like '%phrase%' and if nothing will be find with this method, then the MATCH columnx against (phrase) method should be used.我想如果给定的搜索短语与 DB 中的条目完全匹配,则将选择该条目,如果找不到任何内容,请使用like '%phrase%'进行搜索,如果使用此方法找不到任何内容,则MATCH columnx against (phrase)方法应使用。 This is the code I tried with:这是我尝试使用的代码:

select distinct columnx 
  from tabley 
  where   
      ( CASE when columnx LIKE @word is not null 
             then columnx LIKE @word
             when columnx like concat('%',@word,'%') is not null
             then columnx like concat('%',@word,'%')
             else  MATCH (columnx) AGAINST (@word) END
      );    

To make sure if the cases on a standalone select query works fine I used them separately in where clause.为了确保独立 select 查询上的案例是否正常工作,我在 where 子句中单独使用了它们。 I get result for these queries:我得到了这些查询的结果:

select distinct columnx from view_materialisiert where MATCH (columnx) AGAINST (@word);

and

select distinct columnx from view_materialisiert where columnx like concat('%',@word,'%');

And as expected no result for:正如预期的那样,没有结果:

select distinct columnx from view_materialisiert where columnx like @word;

The question is why i dont get any result when I use the case condition at all?问题是为什么当我使用 case 条件时我没有得到任何结果?

If you want values that match on any of the three condition, you can use boolean logic:如果您想要匹配三个条件中任何一个的值,您可以使用 boolean 逻辑:

select columnx
from tabley
where columnx = @word
   or columnx like concat('%', @word, '%')
   or match(columnx) against (@word)

Or you can extend the case logic:或者您可以扩展case逻辑:

where case
    when columnx = @word                      then 1
    when columnx like concat('%', @word, '%') then 1
    when match(columnx) against (@word)       then 1
end

However I am unsure that's really what you expect.但是,我不确定这是否真的是您所期望的。 It seems like you want to iteratively check the conditions, trying the next one only when the preceding had no match on the entire table.似乎您想迭代地检查条件,仅当前一个在整个表上没有匹配项时才尝试下一个。 This type of logic would be typically implemented with union all and not exists :这种类型的逻辑通常使用union all实现,并且not exists

select columnx
from tabley
where columnx = @word
union all
select columnx
from tabley 
where columnx like concat('%', @word, '%')
    and not exists (select 1 from tabley where columnx = @word)
union all
select columnx
from tabley
where match(columnx) against (@word)
    and not exists (select 1 from tabley where columnx = @word)
    and not exists (select 1 from tabley where columnx like concat('%', @word, '%'))

How the database will optimize such query is highly dependent on your data and other factors.数据库将如何优化此类查询在很大程度上取决于您的数据和其他因素。 In the best case scenario, the following members will be "skipped" as soon as one member returns anything (because the not exists subquery is quite explicit about that), but there is no guarantee.在最好的情况下,只要一个成员返回任何内容,就会“跳过”以下成员(因为not exists子查询对此非常明确),但不能保证。 You would need to assess the performance on your actual dataset.您需要评估实际数据集的性能。

Do only只做

MATCH (columnx) AGAINST ("+word" IN BOOLEAN MODE)

It is very fast.非常快。 That expression eliminates the need for the exact match and some of the other cases.该表达式消除了对精确匹配和其他一些情况的需要。

The OR approaches mentioned are quite inefficient.提到的OR方法效率很低。 They will check every row, usually with every test.他们会检查每一行,通常是每次测试。

Caveats:注意事项:

  • "Short" words cannot be used.不能使用“短”字。
  • "Stop" words cannot be used.不能使用“停止”字样。
  • If you aren't careful about those limitations, you will get nothing or everything.如果您不注意这些限制,您将一无所获。 So do some preprocessing to decide when MATCH will work.所以做一些预处理来决定MATCH什么时候可以工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM