如何选择具有相同ID的行共享一组值?

问题描述:

我正在处理内部搜索引擎(MySQL数据库)的SQL请求。我想让用户搜索精确的表达式,因此当他们搜索"foo bar"时,他们将获得包含foobar的文档,而不仅仅是foobar如何选择具有相同ID的行共享一组值?

search_documents_words表:

| word_id | doc_id | word | 
--------------------------- 
| 1  | 1  | foo | 
| 2  | 1  | bar | 
| 3  | 2  | foo | 

search_documents表:

| doc_id | doc_name | 
--------------------- 
| 1  | mydoc1 | 
| 2  | mydoc2 | 

我想什么:

| doc_id | doc_name | 
-------------------- 
| 1  | mydoc1 | 

假设我有我的关键字在一个PHP数组。

我该如何做到这一点?

+0

那么到目前为止,我只是有一个查询使用'IN'函数 - 这是工作很好,但只适用于“常规搜索”:'SELECT sdoc_id,sdoc_document,sdoc_type FROM search_documents_words,search_documents WHERE sdoc_id = swd_doc AND swd_word IN( “。)join(',',$ _ words)。”)GROUP BY sdoc_id' – vard 2014-09-25 12:45:29

假设你的搜索关键字在阵列

$search = array('foo','bar'); 
$keywords = ''; 
foreach($search as $values) { 
    $keywords .= "'.$values.',"; 
} 
$keywords = rtrim($keywords,","); // creating words as 'foo','bar' 

然后执行此查询

$query = "SELECT B.* 
      FROM search_documents_words A 
      JOIN search_documents B ON A.doc_id = B.doc_id 
      WHERE A.word IN(".$keywords.")"; 

EDITED

如果同一个文件编号不重复的字此情况下将工作(具有许多foo条目的doc 1将不适用于此查询)

$query = "SELECT B.* 
      FROM search_documents_words A 
      JOIN search_documents B ON A.doc_id = B.doc_id 
      WHERE A.word IN(".$keywords.") 
      GROUP BY A.doc_id HAVING COUNT(A.doc_id) = '".count($search)."' "; 
+0

没有安装MySQL,但我认为你在查询之前需要一个DISTINCT B. * – Sparky 2014-09-25 10:28:25

+0

如果我是正确的,这个查询只会看为'foo'或'bar',而不是'foo'和'bar'。这与我用于常规搜索的内容非常相似。 – vard 2014-09-25 12:35:11

+0

查询将看起来像WHERE A.word IN('foo','bar');它会寻找foo和bar。先尝试一下。 – Shafeeque 2014-09-25 12:47:20

您可以使用GROUP_CONCAT和HAVING子句

SELECT sd.doc_id, 
      sd.doc_name, 
GROUP_CONCAT(sdw.word  Order by sdw.word SEPARATOR ' ') AS sdwWord 
    FROM search_documents sd 
    JOIN search_documents_words sdw ON sd.doc_id = sdw.doc_id 
    GROUP BY sd.doc_id, sd.doc_name 
    HAVING sdwWord = <search expression> 
+0

如果关键字的顺序与它们在数据库中的顺序不同,那么如何管理此查询?因为如果'GROUP_CONCAT'返回'bar foo','HAVING'不会接受'foo bar'。除非有一个我不知道的功能,我可以使用它。 – vard 2014-09-25 12:37:40

+0

@vard,好点,添加顺序,它只适用于foo bar位不适用于bar foo,如果您希望bar foo也匹配,则该组合需要添加到search_documents_words表中 – radar 2014-09-25 12:42:15

子查询可以建立这样的:

$keywords = array('foo','bar'); 
foreach($keywords as $key) 
{ 
    $conditions[] = "word='".$key."'"; 
} 
$condition = implode(" AND ",$conditions); 

然后执行此SQL查询:

$query = "SELECT * 
      FROM search_documents 
      WHERE doc_id 
      IN (SELECT doc_id 
       FROM search_documents_words 
       WHERE ".$condition.")" 

希望这有助于!

+0

看起来像正确答案我!我会确认服务器一回来,我希望这不是这个让他崩溃的查询(我有大约30k的关键字和大约5k的文档)。对于记录,这里是查询我结束了:'SELECT sdoc_id,sdoc_document FROM search_documents_words,search_documents WHERE sdoc_id = swd_doc AND sdoc_id IN(SELECT sdoc_id FROM search_documents_words WHERE“。implode('AND',$ conditions)。”)GROUP BY sdoc_id' – vard 2014-09-25 12:42:45