2013-10-11 162 views
2

我正在尝试搜索特定单词的表格。Mysql,PHP,搜索多个词

说我有一个单词列表:打印机,网络,无线,迫切

我只想要回那些所有的这些话都在上面行。

SELECT * FROM tickets WHERE concat(subject,body) REGEXP "printer|network|wireless|urgent" 

将返回任何一个这样的单词。我怎样才能让它只返回那些所有这些单词都在其中的行。

感谢,

+0

是必须显示固定或可变的单词的数量? – TheWolf

+0

最好是一个变量。 – DanielOlivasJr

+1

你可以做'LIKE'%word1%'并且'%word2%'和'',虽然表现不会很好。如果您一般在执行关键字搜索,您可能希望查看文本索引基本系统,例如Zend Lucene(基于PHP,如果您不介意使用其他语言,还有其他语言)。 – halfer

回答

6

有两种方法可以做到这一点。首先是相当明显的方法。比方说,你都需要出现在阵列的话叫$ necessaryWords:

$sql = 'SELECT ... FROM ...'; // and so on 
$sql .= ' WHERE 1'; 

foreach ($necessaryWords as $word) 
    $sql .= ' AND concat(subject,body) LIKE "%' . $word . '%"'; //Quotes around string 

但是,使用%foo%是相当缓慢的,因为没有任何指标可以使用,所以这个查询可能会导致巨大的表的性能问题和/或大量必要的单词。

另一种方法是在subjectbody上的FULLTEXT索引。你可以使用全文MATCH IN BOOLEAN MODE这样的:

$sql = 'SELECT ... FROM ...'; // and so on 
$sql .= ' WHERE MATCH(subject,body) AGAINST("'; 

foreach ($necessaryWords as $word) 
    $sql .= ' +' . $word; 
$sql .= '")'; 

请注意,您的表必须为了使用MyISAM使用FULLTEXT索引。 UPDATE:As of MySQL 5.6,InnoDB也支持FULLTEXT索引。我想这可能是更好的选择性能明智。关于全文布尔模式的更多文档可以在manual中找到。

+0

@DobotJr:对于这个页面的好奇心和可能的未来访问者:你选择了哪个版本,为什么? – TheWolf

1

不是最好的方法,但是:

SELECT * FROM tickets WHERE 
concat(subject,body) REGEXP "printer" AND 
concat(subject,body) REGEXP "network" AND 
concat(subject,body) REGEXP "wireless" AND 
concat(subject,body) REGEXP "urgent" 
0
SELECT * FROM tickets WHERE 
    concat(subject,body) LIKE "%printer%" AND 
    concat(subject,body) LIKE "%network%" AND 
    concat(subject,body) LIKE "%wireless%" AND 
    concat(subject,body) LIKE "%urgent%" 
0

备选答案,只是因为我想到这一点时,我看着你的问题。我不知道是否会比其他的答案(很可能没有)速度快:

(SELECT * FROM tickets WHERE subject LIKE "%printer%" OR body LIKE "%printer%") 
UNION 
(SELECT * FROM tickets WHERE subject LIKE "%network%" OR body LIKE "%network%") 
UNION 
(SELECT * FROM tickets WHERE subject LIKE "%wireless%" OR body LIKE "%wireless%") 
UNION 
(SELECT * FROM tickets WHERE subject LIKE "%urgent%" OR body LIKE "%urgent%") 

UPDATE: 这是错误的

+0

这将返回包含任一单词的所有行。 – TheWolf

+0

哈哈我认为结束了当天的综合征(再次) – Populus