【问题标题】:SQL search for words in any orderSQL 以任意顺序搜索单词
【发布时间】:2015-09-30 18:36:17
【问题描述】:

鉴于这个模型:

+-----------+-------------+---------------------------+
|  item_id  |  item_name  |  desc                     |
+-----------+-------------+---------------------------+
|  1        |  Product 1  |  lorem ipsum dolor...     |
|  2        |  Product 2  |  lorem mauris eu...       |
|  3        |  Product 3  |  scelerisque sagittis...  |
|  4        |  Product 4  |  lorem dolor ipsum...     |
|  5        |  Product 5  |  ipsum dolor lorem...     |
+-----------+-------------+---------------------------+

我想搜索在item_name 或desc 中包含单词lorem ipsum 的所有产品。此外,lorem 和 ipsum 之间可以出现任何单词,lorem 和 ipsum 可以按任何顺序出现。基本上,此搜索将返回项目 1、4 和 5

现在,我知道我可以做到这一点:

SELECT * FROM items
WHERE (item_name LIKE 'lorem%ipsum'
       OR desc LIKE 'lorem%ipsum')
OR (item_name LIKE 'ipsum%lorem'
    OR desc LIKE 'ipsum%lorem')

但如果我的搜索词更长(即 lorem ipsum dolor sit amet、consectetur adipiscing elit),我觉得在查询中添加 OR 的数量可能会变得有点荒谬。有没有更简单/更有效的方法来处理这个问题?

【问题讨论】:

  • 你可以试试WHERE (item_name like '%lorem%' and item_name like '%ipsum%') OR (desc like '%lorem%' and desc like '%ipsum%')。这需要所有搜索字词,但顺序不限,在任一列中。

标签: mysql sql


【解决方案1】:

这种搜索要求听起来很适合full text search。

全文搜索(或至少可以)更像是一个类似于搜索的“搜索引擎”,而不是传统的 sql like 搜索。使用全文搜索,搜索单词的顺序无关紧要,并且根据 RDBM,一些全文搜索功能允许同义词查找以及噪声词过滤。

在(我相信)大多数情况下,全文搜索比like 搜索要快得多。 Here是一篇关于mysql全文搜索入门的文章。

mySql全文搜索语法示例:

select *
from items
where match(item_name) against ('+lorem +ipsum' in boolean mode)

全文搜索确实有一定的要求(在文章中的链接中有详细说明)。我没有亲自使用mysqls 全文搜索,或者我会列出这些步骤。如果您想朝那个方向发展,应该足以让您开始。

【讨论】:

  • 注意:如果你想要部分单词 '+lorem*',星号有效
  • zend 文章的链接现已失效。
【解决方案2】:

我认为单独查找每个单词更简单:

SELECT *
FROM items
WHERE (item_name like '%lorem%' and item_name like '%ipsum%') or
      (`desc` like '%lorem%' and `desc` like '%ipsum%');

这很容易推广到更多的单词和更多的列。

如果您愿意,可以将这些值连接在一起。但是,如果您希望两个值在同一个字段中,那么单独的逻辑会更清晰。

另外,如果您真的在寻找单词,那么全文搜索是一个不错的选择,并且性能会更好。

【讨论】:

    【解决方案3】:
    declare @search varchar(255) = 'your search';
    
    select * from [Person] p
    
    WHERE (select COUNT(VALUE) from STRING_SPLIT(@search,' ') where CHARINDEX(VALUE,p.Name)>0) = (select COUNT(VALUE) from STRING_SPLIT(@search,' '));
    

    【讨论】:

      猜你喜欢
      • 2017-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-15
      • 1970-01-01
      • 1970-01-01
      • 2018-07-12
      • 2022-01-18
      相关资源
      最近更新 更多