在WHERE子句中使用mysql concat()函数?

57

我想在我的表格中搜索名字和姓氏两列。我目前从一个字段接受搜索项,并将其逐个与这两列进行比较。

    select * from table where first_name like '%$search_term%' or 
    last_name like '%$search_term%';

这对于单个单词搜索项可以正常工作,但结果集包括了所有名为"Larry"的人。但是如果有人输入了名字和空格,然后是姓氏,我想要更窄的搜索结果。我已经尝试过以下方法但没有成功。

    select * from table where first_name like '%$search_term%' or last_name 
    like '%$search_term%' or concat_ws(' ',first_name,last_name) 
    like '%$search_term%';

有什么建议吗?

编辑:我正在测试的姓名是 "Larry Smith"。数据库将 "Larry" 存储在 "first_name" 列中,"Smith" 存储在 "last_name" 列中。数据干净,没有额外的空格,并且搜索词被修剪过。

编辑 2:今天早上我试了 Robert Gamble 的答案。他的答案与我昨晚运行的非常相似。我无法解释,但今天它可以正常工作。我唯一能想到的区别是,昨晚我将 concat 函数作为搜索查询的第三个“或”段落运行(在查找 first_name 和 last_name 后)。今天早上,我在查找以上信息以及地址和商业名称后才运行它。

在查询末尾运行mysql函数比在中间运行更好吗?


我刚刚运行了你遇到问题的那个版本,对我来说它可以正常工作。 - Robert Gamble
7个回答

103

你现有的代码应该可以工作,但可以简化为:

select * from table where concat_ws(' ',first_name,last_name) 
like '%$search_term%';
你能提供一个例子名称和搜索术语,说明这种情况不起作用吗?

所有数据库都支持这种语法或类似的语法吗?这在SQL标准中有提到吗? - Rohit Banga
有没有一种方法可以在所有数据库中以不同的方式实现这个功能? - Rohit Banga
这个问题可以用两个不同的表来解决,因为我的情况需要用到不同的表。 - PinoyStackOverflower
你知道这个查询是否可以使用索引吗? - AbcAeffchen

14

请注意搜索查询现在区分大小写。

在使用时

SELECT * FROM table WHERE `first_name` LIKE '%$search_term%'

这个模式将匹配"Larry"和"larry"。但是使用concat_ws后,它会突然变得区分大小写!

可以通过使用以下查询语句来解决:

SELECT * FROM table WHERE UPPER(CONCAT_WS(' ', `first_name`, `last_name`) LIKE UPPER('%$search_term%')

编辑:请注意,此方法仅适用于非二进制元素。另请参见mynameispaulie的回答


2
如果您正在连接整数字段,则大小写敏感性也可能是 MySQL 版本 5.5 之前的错误结果 - 请参阅此答案 - TheStoryCoder

5
SELECT *,concat_ws(' ',first_name,last_name) AS whole_name FROM users HAVING whole_name LIKE '%$search_term%'

...可能是你想要的。


4

致Luc:

我同意你的答案,但我想补充一点,UPPER函数只适用于非二进制元素。如果你正在处理例如AGE列(或任何数字),你需要执行CAST转换才能使UPPER函数正常工作。

SELECT * FROM table WHERE UPPER(CONCAT_WS(' ', first_name, last_name, CAST(age AS CHAR)) LIKE UPPER('%$search_term%');

抱歉我无法直接回复Luc的答案,因为我实在想不出该怎么做。如果管理员可以移动我的帖子,请移动一下。


欢迎来到Stack Overflow!留下评论需要50声望。对于有帮助的访客来说,这可能很烦人,但它也减少了无关的闲聊。在任何情况下,将应该作为评论的内容发布为答案是不被赞同的,但由于您提供了解决问题相关的信息,这可能是可以接受的。 - C. A. McCann
五十是相当高的限制 :/ 无论如何,我给你的答案点了赞(+10声望),并在我的帖子中链接到它。感谢你的贡献 :) - Luc
如果您将整数字段连接起来,大小写敏感性可能是 MySQL 5.5 版本之前存在的错误的结果 - 请参阅此[答案](https://dev59.com/8Gw15IYBdhLWcg3wy-vO)。 - TheStoryCoder

2
你可以在MySQL中(也可能适用于其他SQL)进行这项工作。尝试以下操作:
select * from table where concat(' ',first_name,last_name) 
    like '%$search_term%';

1

有几个事情可能会妨碍 - 你的数据干净吗?

可能是你的名字字段末尾有空格,这意味着在连接它们时,名字和姓氏之间会有两个空格?使用trim(first_name)/trim(last_name)可以解决这个问题 - 尽管真正的解决方法是更新你的数据。

你还可以这样匹配两个词都出现但不一定在一起(假设你在使用PHP - 根据$search_term变量所示)。

$whereclauses=array();
$terms = explode(' ', $search_term);
foreach ($terms as $term) {
    $term = mysql_real_escape_string($term);
    $whereclauses[] = "CONCAT(first_name, ' ', last_name) LIKE '%$term%'";
}
$sql = "select * from table where";
$sql .= implode(' and ', $whereclauses);

-2
你可以尝试这个:
select * FROM table where (concat(first_name, ' ', last_name)) = $search_term;

2
你需要在 '$search_term' 上添加括号。 - Naruto
1
这还要求用户输入的名称必须完全匹配,而不是部分匹配(例如:“Pat” 与“Pat”和“Patrick”匹配)。 - Phil M

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接