我想搜索一个特定字段的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数据库执行此操作?
答案 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次表扫描。联合和派生表执行3.前两个用于过滤出模式的列,然后是子集上的第三个用于查找它们相等的位置 - 因为union会过滤掉dupes。
根据模式的位置给出真正的排序。 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
对于喜欢和索引的二进制真/假的工作订单应该从索引中受益