我想写一个查询,它将按顺序获取给定字符串及其子字符串的最近匹配字符串。
例如,假设我在列中拥有所有名称的表。如果我想搜索名称"ATUL"
,则结果应列出所有不同的名称,首先匹配"ATUL%"
然后"ATU%"
然后"AT%"
然后"A%"
,最后是所有剩余记录
(然后我将根据我的需要从中获取前N条记录)
独特的查询联合是我能想到的一个解决方案。有没有更有效的方法来做到这一点?
更新
感谢下面的答案。同时我自己尝试了一些东西,发现这个查询产生了预期的结果,前提是我 用户名 列已编入索引
select * FROM all_usernames WHERE (username LIKE 'atul%') or (username LIKE 'atu%') or (username LIKE 'at%') or (username LIKE 'a%') or (username LIKE '%');
但它是标准行为还是我只是巧合地得到它?
答案 0 :(得分:2)
一种方法是在like
:
order by
order by (case when name like 'ATUL%' then 1
when name like 'ATU%' then 2
when name like 'AT%' then 3
when name like 'A%' then 4
else 5
end)
更通用的方法也是暴力,但可能会这样:
order by (case when left(name, 9) = left('ATUL', 9) then 1
when left(name, 8) = left('ATUL', 8) then 2
when left(name, 7) = left('ATUL', 7) then 3
when left(name, 6) = left('ATUL', 6) then 4
when left(name, 5) = left('ATUL', 5) then 5
when left(name, 4) = left('ATUL', 4) then 6
when left(name, 3) = left('ATUL', 3) then 7
when left(name, 2) = left('ATUL', 2) then 8
when left(name, 1) = left('ATUL', 1) then 9
end)
答案 1 :(得分:0)
嗯,ATUL%
,ATU%
和AT%
都是A%
的子集,因此只需选择A%
即可获得所有结果。棘手的部分是按照多少个第一个字符匹配它们。似乎没有简单或优雅的方法来找到它,所以如果你想要通用的东西,你将不得不编写自己的函数,在循环中比较字符串1和字符串2的子字符串,直到它们不同或任一字符串的长度为到达了,就像这样:
CREATE FUNCTION `compare_first_chars`(str1 varchar(1000), str2 varchar(1000))
RETURNS int
DETERMINISTIC
BEGIN
DECLARE v_offset INT;
DECLARE v_minlen INT;
IF str1 is null or str2 is null THEN
return 0;
END IF;
SET v_offset = 0;
SET v_minlen = least(length(str1), length(str2));
count_loop: LOOP
SET v_offset = v_offset + 1;
IF v_offset > v_minlen THEN
LEAVE count_loop;
END IF;
IF substr(str1, 1, v_offset) != substr(str2, 1, v_offset) THEN
LEAVE count_loop;
END IF;
END LOOP;
RETURN v_offset-1;
END
然后你可以order desc
。如果你不需要复杂的东西,那么按顺序使用CASE
,或者如你在回答中提到的那样使用不同的联合。