我需要搜索两个字段使用相似的功能,并应该匹配也以相反的顺序。我的表使用InnoDB,它没有全文搜索。
考虑以下情况:
我有带有first_name和last_name列的users表。在它上,有一个具有以下值的行:
{
first_name: 'Ludwig',
last_name: 'van Beethoven',
}
案例:
我尝试过这个SQL语句,但没有成功。
SELECT CONCAT(first_name, ' ', last_name) as fullname
FROM users
WHERE fullname LIKE '%Ludwig van Beethoven%';
发布于 2010-03-18 11:24:25
您需要在where子句中重新声明concat表达式。
SELECT CONCAT(first_name, ' ', last_name) as fullname
FROM users
WHERE CONCAT(first_name, ' ', last_name) LIKE '%doe%';
不幸的是,"as“只是创建一个列别名,而不是可以在其他地方使用的变量。
发布于 2010-03-18 11:30:43
最主要的事
确保在first_name
和last_name
上有一个复合索引。否则,不管您如何处理,都很容易完成一个完整的表扫描。因此,如果您还没有一个,那么创建一个:
CREATE INDEX users_firstandlast ON users(first_name, last_name);
语法选项
一旦索引到位,您就有了一些选项:
选项1:正如威利斯·布莱克本所说,在WHERE
子句中重复CONCAT
(因为AS
没有创建可以在WHERE
子句中使用的名称):
SELECT CONCAT(first_name, ' ', last_name) as fullname
FROM users
WHERE CONCAT(first_name, ' ', last_name) LIKE '%doe%';
使用EXPLAIN
检查特定情况,但是在我的测试中,它说它使用复合索引,即使在WHERE
子句中使用了一个函数。
选项2:在这种情况下,您可以在WHERE
子句中始终使用两个LIKE
:
SELECT CONCAT(first_name, ' ', last_name) as fullname
FROM users
WHERE first_name LIKE '%doe%' or last_name LIKE '%doe%';
同样,这可以使用复合索引(而它不会使用first_name
和last_name
列上的单独索引--如果您没有使用通配符,但是根据EXPLAIN
和您的里程可能有所不同,总是检查,在这种情况下,它会与表扫描一起使用)。
选项3 In 他的回答,Andy说您可以使用HAVING
实现这个功能。我的阅读MySQL手册建议它首先构建结果集,然后在将其发送到客户端之前在最后应用HAVING
,所以我会对此持怀疑态度。但是,在我的快速和肮脏的测试中,EXPLAIN
告诉我,如果您有上面提到的复合索引,那么HAVING
版本会进行索引搜索,而不是表扫描。如果使用真实数据进行的测试证实了这一点,那么这可能是一个很好的选择。以这种方式使用HAVING
是一个MySQL扩展(不是标准的),但是CONCAT
也是如此,所以我们已经进入了MySQL特定的东西。
结论
如果您还没有创建索引,那么我将使用选项2(如果可能的话);否则,选择1,除非您能够找到(或者Andy可以提供)一个引用,用于没有构建大量临时结果集的HAVING
(如果不是标准的话,如果没有),这将是非常酷的。无论如何,在您的特定环境中,使用EXPLAIN
进行检查并进行测试。
发布于 2011-10-29 11:44:27
从“%Ludwig%”或“%Ludwig%”(first_name,‘',first_name)这样的用户中选择*;
所有返回的搜索案例包括“贝多芬·路德维希”。
https://stackoverflow.com/questions/2469359
复制相似问题