如何选择具有相同ID的行共享一组值?
我正在处理内部搜索引擎(MySQL数据库)的SQL请求。我想让用户搜索精确的表达式,因此当他们搜索"foo bar"
时,他们将获得包含foo
和bar
的文档,而不仅仅是foo
或bar
。如何选择具有相同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数组。
我该如何做到这一点?
假设你的搜索关键字在阵列
$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)."' ";
您可以使用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>
子查询可以建立这样的:
$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.")"
希望这有助于!
看起来像正确答案我!我会确认服务器一回来,我希望这不是这个让他崩溃的查询(我有大约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
那么到目前为止,我只是有一个查询使用'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