【问题标题】:How can I search into two columns and sort the result by priority?如何搜索到两列并按优先级对结果进行排序?
【发布时间】:2017-08-04 17:30:48
【问题描述】:

我有一张这样的桌子:

-- users
+----+------------+-------------+
| id | first_name |  last_name  |
+----+------------+-------------+
| 1  | John       | Kooper      |
| 2  | Martin     | Koop        |
| 3  | Koop       | Sth         |
| 4  | Jack       | Linoff      |
+----+------------+-------------+

这是一个包含我网站用户的表格。现在我想在它们中搜索。您的查询建议是什么?


这是我当前的查询:

SELECT u.*
FROM users 
WHERE first_name LIKE :input%
   OR last_name LIKE :input%
   OR CONCAT(first_name, last_name) LIKE :input%

如您所见,我的查询只是搜索,没有别的。没有任何ORDER BY 子句,因此没有定义优先级。你知道,我要做的就是实现类似这个搜索引擎的东西:

无论如何,有人如何为我的查询实现优先级?例如,如果您搜索Koop,则结果的第一行应该是表格中的第二行,因为last_name 列应该具有更大的优先级(比first_name 列)koop 是表格第二行的 last_name 的确切值。

这是:input = 'koop' 的预期结果:

+----+------------+-------------+
| 2  | Martin     | Koop        |
| 1  | John       | Kooper      |
| 3  | Koop       | Sth         |
+----+------------+-------------+

我该怎么做?

【问题讨论】:

  • 全文搜索可能会有所帮助。顺便问一下,杰克林诺夫是谁 ^ ^ ?
  • (1) 您的查询中有错字:last_name LIKR 和 (2) 您可以使用 ORDER BY 来订购结果和 (3) 您在 SO 上看到的“优先级”是基于该用户的声誉。寻找外部来源对数据进行排序(例如,其他列或加入其他表)。
  • 我认为您的问题是“如何根据任意标准识别搜索结果的相关性。答案是,1. 确定相关性标准,2. 实施它!如果您遇到困难,快来告诉我们

标签: mysql sql search-engine


【解决方案1】:

考虑使用 FULLTEXT 搜索。

SELECT *,
    MATCH (`first_name`) AGAINST (':input*' IN BOOLEAN MODE) AS `relevance_first_name`,
    MATCH (`last_name`) AGAINST (':input*' IN BOOLEAN MODE) AS `relevance_last_name`
FROM `users`
WHERE MATCH (`first_name`, `last_name`) AGAINST (':input*' IN BOOLEAN MODE)
ORDER BY (`relevance_first_name`)+(`relevance_last_name`*4) DESC

【讨论】:

  • 看起来不错,谢谢。赞成。请你告诉我你为什么使用IN BOOLEAN MODE
  • 搜索通配符 :input* - asterisk(*)
【解决方案2】:

您可以使用ORDER BY 列... 例如,您可以先按姓氏排序,然后再按名字排序。

SELECT u.* FROM users 
    WHERE first_name LIKE :input%
        OR last_name LIKR :input%
        OR CONCAT(first_name, last_name) LIKE :input%
    ORDER BY last_name, first_name;

更新 在您的 cmets 中,如果您想按优先级排序,即评级或其他任何内容,您应该使用 ORDER BY users._column_name 或加入另一个评级列所在的表,并按此列对结果进行排序。

【讨论】:

    【解决方案3】:

    一个简单的解决方案可以是 order by 子句中的 (switch) case 语句,如下所示:

    SELECT u.*
    FROM users 
    WHERE first_name LIKE :input%
    OR last_name LIKE :input%
    OR CONCAT(first_name, last_name) LIKE :input%     
    ORDER BY 
    (CASE WHEN first_name = :input THEN 1 
          WHEN first_name LIKE :input% THEN 2 (....) ELSE 99 END) ;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-09
      • 2018-02-10
      • 1970-01-01
      • 1970-01-01
      • 2011-06-24
      • 1970-01-01
      • 2012-06-25
      相关资源
      最近更新 更多