【问题标题】:Order results by "Best Match" SQL按“最佳匹配”SQL 排序结果
【发布时间】:2021-10-02 07:26:14
【问题描述】:

我正在开展一个项目,该项目要求用户搜索某些类别的产品。产品有标签,例如:T 恤、套头衫、帽子,我目前正在显示按喜欢数量排序的结果。这是我的 SQL 语句:

SELECT * 
FROM products 
WHERE keywords LIKE '%$query%' 
ORDER BY likes DESC LIMIT 50;

但问题是,如果有人搜索“帽子”,但在数据库中一个更流行的词是“chatterbox”,它会首先提出这个词,因为它有更多的喜欢。

所以把它放在伪代码中:

SELECT * 
FROM products 
WHERE keywords LIKE '%$query%' 
ORDER BY "BEST MATCH" LIMIT 50;

理想的结果是:

2 个结果:
帽子:26 个赞,
C帽子terbox:234个赞,

代替:

2 个结果:
C帽子terbox:234 个赞,
帽子:26 个赞,

那么有没有办法做到这一点?

【问题讨论】:

  • 只是作为一个提示:对于纯数据库的这项工作,您可能会很快达到限制。即使您发现“帽子”应该首先出现(这是绝对正确的),您也可能会发现“帽子”应该出现在“聊天框”之前。如果这是您想要的,您可能会考虑“相关性”一词,并查看专门为此类工作设计的搜索引擎。
  • 附带说明,请注意您的 SQL 查询没有受到 SQL 注入攻击的保护。使用绑定参数而不是字符串插值。
  • @at54321 是的,谢谢!这只是一个示例,实际代码略有不同,但我感谢您的帮助:)

标签: php mysql sql database sql-like


【解决方案1】:

ORDER BY 子句中,首先检查是否存在完全匹配或(如果需要)keywords'$query' 开头:

SELECT * 
FROM products 
WHERE keywords LIKE '%$query%' 
ORDER BY keywords = '$query' DESC, -- 1st keywords with exact match
         keywords LIKE '$query%' DESC, -- 2nd keywords which start with '$query'    
         likes DESC -- 3d likes
LIMIT 50;

【讨论】:

  • 另外,如果你想对开头的词处理优先级更高的搜索词,你可以看看POSITION函数,它的结果可以添加到ORDER BY 子句。
  • @at54321 在这种情况下不需要函数。 LIKE 也可以使用。
【解决方案2】:

你可以试试这个:

(SELECT * FROM products WHERE keywords LIKE '$query')
union
(SELECT * FROM products WHERE keywords LIKE '%$query%' order by likes desc LIMIT 50);

第一个查询得到完全匹配,第二个查询则按喜欢的顺序匹配。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-14
    • 1970-01-01
    • 2016-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多