【问题标题】:SQL search name and sort by best fitSQL 搜索名称并按最佳匹配排序
【发布时间】:2015-08-08 17:20:15
【问题描述】:

我有一个带有商店数据库的网站。我网站的访问者可以按名称搜索商店,目前 SQL 查询是这样完成的:

SELECT * 
FROM tbl_shop 
WHERE LOWER(`name`) LIKE LOWER(`%text1%`) 
   OR LOWER(`name`) LIKE LOWER(`%text2%`) 
   ..... 
   OR LOWER(`name`) LIKE LOWER(`%textN%`)

这很好用,但问题是,结果不是按最佳匹配排序的。一些商店名称包含非常常见的单词(例如“Na Lavce”),如果您输入此字符串,所有包含“%na%”(很多)的沙龙都会显示为结果。

因此,访问者可以获得许多结果,但有时无法找到他正在寻找的内容,因为正确的结果例如在第 5 个结果页上。任何想法如何解决这个问题?

【问题讨论】:

  • 您可以轻松地按匹配数对它们进行排名,还可以为术语的顺序分配偏好。但是你怎么知道哪个更好呢?
  • 您还可以设置常用词列表并避免搜索这些词,但这需要一些预处理。
  • 很多常用词也是较短的词。您可以以某种方式按搜索词的长度进行排名,但我一开始并没有这么说,因为我不确定它是否可靠。
  • 大多数数据库都支持fulltext匹配,这听起来像你想要实现的
  • 为什么不使用下拉菜单(具有自动选择功能)来限制用户列表?

标签: mysql sql database search


【解决方案1】:
SELECT * 
FROM tbl_shop 
WHERE 
       LOWER(`name`) LIKE LOWER(`%text1%`) 
   OR  LOWER(`name`) LIKE LOWER(`%text2%`) 
   ..... 
   OR  LOWER(`name`) LIKE LOWER(`%textN%`)
ORDER BY
   CASE WHEN LOWER(`name`) LIKE LOWER(`%text1%`) THEN 1 ELSE 0 END +
   CASE WHEN LOWER(`name`) LIKE LOWER(`%text2%`) THEN 1 ELSE 0 END +
   .....
   CASE WHEN LOWER(`name`) LIKE LOWER(`%textN%`) THEN 1 ELSE 0 END
   DESC

如果您想按词条排序:

ORDER BY
   CASE WHEN LOWER(`name`) LIKE LOWER(`%text1%`) THEN 1024 ELSE 0 END +
   CASE WHEN LOWER(`name`) LIKE LOWER(`%text2%`) THEN  512 ELSE 0 END +
   CASE WHEN LOWER(`name`) LIKE LOWER(`%text2%`) THEN  256 ELSE 0 END +
   .....
   CASE WHEN LOWER(`name`) LIKE LOWER(`%textN%`) THEN    1 ELSE 0 END
   DESC

【讨论】:

  • 谢谢,马上试试。术语的顺序是随机的(访问者输入它们)所以它可能不适合我,对吧?
  • 我发现,排序是在我的应用程序中按属性完成的(返回行的顺序被忽略),所以我需要将排名添加到查询结果中......可能是这样的吗? SELECT *, (CASE WHEN LOWER( name`) LIKE LOWER('%text1%') THEN 1 ELSE 0 END + CASE WHEN LOWER(name) LIKE LOWER('%text2%') THEN 1 ELSE 0 END) 作为来自 tbl_salon 的订单 WHERE LOWER (name) LIKE LOWER('%text1%') OR LOWER(name) LIKE LOWER('%text2%') ORDER BY order` 这个有语法错误,但我正在寻找类似的东西
  • 尝试其他名称。 "order" 是一个保留字,如果你真的需要这样使用,你需要用引号括起来。
  • 我不会说订单是“随机的”。但是用户必须知道搜索条件中的重要术语,并且期望这样做可能是不合理的。
  • 我尝试了不同的词,然后是“订单”,它奏效了。谢谢:-) 最终代码如下所示:SELECT *, (CASE WHEN LOWER(name) LIKE LOWER('%text1%') THEN 1 ELSE 0 END + CASE WHEN LOWER(name) LIKE LOWER('% text2%') THEN 1 ELSE 0 END) AS 来自 tbl_shop 的东西 WHERE LOWER(name) LIKE LOWER('%text1%') OR LOWER(name) LIKE LOWER('%text2%') ORDER BY something DESC ;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-02
  • 2014-03-28
  • 2011-05-23
  • 2013-09-14
  • 2016-11-12
  • 1970-01-01
相关资源
最近更新 更多