2013-03-02 68 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