SQL语句的WHERE子句中的加权条件

时间:2011-02-17 23:47:37

标签: mysql sql where

我想搜索一个特定字段的STARTS带有一些字符串(让我们说“ar”)或字段CONTAINS字符串“ar”的记录。

但是,我认为这两个条件不同,因为我将返回的结果数量限制为10,并且我希望STARTS WITH条件的权重比CONTAINS条件更重。

示例:

SELECT *
FROM Employees
WHERE Name LIKE 'ar%' OR Name LIKE '%ar%'
LIMIT 10

问题在于,如果有名称以“ar”开头,则应该受到青睐。我应该找回一个只包含“ar”的名字的唯一方法就是如果只有10个以“ar”开头的名字

如何针对MySQL数据库执行此操作?

5 个答案:

答案 0 :(得分:11)

您需要分两部分选择它们,并在结果中添加一个Preference标签。每个段10个,然后合并它们并再次取得最好的10.如果段1产生8个条目,那么UNION ALL的段2将产生剩余的2个

SELECT *
FROM
(
SELECT *, 1 as Preferred
FROM Employees
WHERE Name LIKE 'ar%'
LIMIT 10
UNION ALL
SELECT *
FROM
(
    SELECT *, 2
    FROM Employees
    WHERE Name NOT LIKE 'ar%' AND Name LIKE '%ar%'
    LIMIT 10
) X
) Y
ORDER BY Preferred
LIMIT 10

答案 1 :(得分:4)

为结果分配代码值,并按代码值排序:

select
    *,
    (case when name like 'ar%' then 1 else 2 end) as priority
from
    employees
where
    name like 'ar%' or name like '%ar%'
order by
    priority
limit 10

修改

如果可能存在大量匹配,请参阅Richard aka cyberkiwi的答案以获得更有效的解决方案。

答案 2 :(得分:1)

我的解决方案是:

SELECT *
FROM Employees
WHERE Name LIKE '%ar%'
ORDER BY instr(name, 'ar'), name
LIMIT 10

instr()查找第一次出现的模式。 AR%将出现在xxAR之前。

这可以防止:

  1. 只能进行1次表扫描。联合和派生表执行3.前两个用于过滤出模式的列,然后是子集上的第三个用于查找它们相等的位置 - 因为union会过滤掉dupes。

  2. 根据模式的位置给出真正的排序。 Wx> xW> xxW>等...

答案 3 :(得分:0)

试试这个(没有可立即测试的MySQL实例):

SELECT * FROM
   (SELECT * FROM Employees WHERE Name LIKE 'ar%'
    UNION
    SELECT * FROM Employees WHERE Name LIKE '%ar%'
   )
 LIMIT 10

可能有更好的方法可以做到这一点,但马上就想到了。

答案 4 :(得分:0)

SELECT *
FROM Employees
WHERE Name LIKE 'ar%' OR Name LIKE '%ar%'
ORDER BY LIKE 'ar%' DESC
LIMIT 10

对于喜欢和索引的二进制真/假的工作订单应该从索引中受益