2013-03-02 67 views
1

我有一个名为users的表,其中包含firstnamelastname列。摆脱WHERE子句中的函数

我在如何构造WHERE子句来返回匹配的名字,姓氏,名字加空格和姓氏,姓氏加上逗号和名字的结果上挣扎。例如,“John”,“Doe”,“John Doe”和“Doe,John”。它也应该用于部分补丁(即“John D”)。我正在考虑类似以下内容(用搜索词替代?)。

SELECT * FROM people WHERE 
firstname LIKE ? 
OR CONCAT_WS(" ",firstname,lastname) LIKE ? 
OR lastname LIKE ? 
OR CONCAT_WS(", ",lastname,firstname) LIKE ? 

没有以这种方式作为搜索的“李四”,也将返回“约翰·恩德斯”有点小瑕疵,“约翰Flaggens”和“约翰Goodmen”,所以我需要一些有条件的加入只要在给定两个名字时姓名和名字都匹配就返回结果。

这种方法也有一个很大的缺陷,因为我在我的WHERE子句中有函数阻止使用索引并导致性能显着下降。

我可以在没有使用WHERE子句中的函数的情况下仅使用SQL来有效地执行此操作,还是应该使用服务器代码(即PHP)解析给定的空格和逗号搜索短语,并根据结果创建动态SQL查询?

+0

如果你想要做的这些类型的搜索,你可以考虑全文在MySQL中搜索功能。 – 2013-03-02 19:25:45

+0

@戈登林诺夫。感谢您的评论。我可以问你为什么推荐这么做吗? – user1032531 2013-03-02 19:32:49

+0

您正在尝试使SQL'like'命令适应更全面的文本搜索需求。全文搜索可能会为您提供更好的框架来实现所需功能。 – 2013-03-02 19:34:17

回答

1

,你询问是否可以有效做到这一点MySQL中给出的模式设计,而无需使用FULLTEXT搜索简单的答案是否定的,你不能有效地做到这一点。

您可以使用LIKE/STRCMP和/或string functions创建一些古怪的查询。如果你采用这种方法,编写一些应用程序逻辑以内联方式创建查询将会好得多,而不是写一个能处理所有事情的查询。无论哪种方式,它不可能是真正有效的

MySQL 5.6有能力在INNODB内执行FULLTEXT搜索。如果您使用的是较低版本,则只能使用MyISAM表执行此操作 - MyISAM可能不是一个好主意的原因很多。

另一种方法是看一个真实的搜索解决方案,如LuceneSphinxXapian

+0

感谢史蒂夫,我正在使用MySQL 5.5.28并使用INNODB。我会研究FULLTEXT以及其他推荐的真正搜索解决方案。 – user1032531 2013-03-02 19:41:59