我有3个MySQL表:
blog_posts // Contains blog posts
blog_tags // Contains tags
rel__blog_post_tags // Relates tags to a blog post (refering relation IDs)
这是我的PHP代码:
// I get tags from URL: /tag/tag1;tag2;tag3
$tags = explode(';', $options['req_tags']);
// Prepare for prepared SQL query
$in = str_repeat('?,', count($tags) - 1) . '?';
// Prepare SQL param array as I need to mix category ID with tags...
$sql_params = $tags;
// This SQL will select with IN (equals to OR but want to change to AND)
$sql_get_posts = '
SELECT * FROM blog_posts
WHERE category_id = ?
AND post_id IN
(SELECT post_id FROM rel__blog_post_tags
WHERE tag_id IN (' . $in . '));';
// Prepare the query
$get_posts = $PDO->prepare($sql_get_posts);
// Add category ID to beginning of array of SQL params (in front of tags)
array_unshift($sql_params, $options['category_id']);
// Now execute and get blog posts to array
$get_posts->execute($sql_params);
$postdata = $get_posts->fetchAll();
?>
好的,我的问题在于我使用" WHERE tag_id IN ..."。这将返回匹配的任何博客帖子:
...AND post_id IN (SELECT post_id FROM rel__blog_post_tags WHERE tag_id='tag1' OR tag_id='tag2' OR tag_id='tag3'... and so on.
所以基本上,我不能通过添加更多标签来缩小我的博客文章结果,这就是我所追求的。
如何更改此SQL查询以使其如下所示,以便如果我有一个带有ID的博客文章" foobar"并且它与数据库中的tag1和tag2有连接,它不会显示,因为我正在寻找带有ID" foobar"的博客文章。标签为tag1,tag2和tag3:
...AND post_id IN (SELECT post_id FROM rel__blog_post_tags WHERE tag_id='tag1' AND tag_id='tag2' AND tag_id='tag3'... And so on...
答案 0 :(得分:2)
你可以通过创建"和tag_id =?"的集合来修复它。字符串使用for循环。 如下所示:
for($i=0; $i<count($tags);$++){
if($i=0){
$condition="tag_id=$tags[$i]";
}
else{
$condition.="and tag_id=$tags[$i]";
}
}
答案 1 :(得分:1)
这不起作用的原因是select语句正在分析每一行。单行只能有一个tag_id值。当您使用AND时,您正在检查该行的tag_id是否等于多个值,这些值永远不会为真。
在一个现实世界的例子中,我不能同时穿鞋和靴子。
答案 2 :(得分:0)
我根据这个问题撰写了一篇博客文章http://www.kurungkurawal.com/2015/03/23/sql-filter-data-berdasarkan-beberapa-baris-data/,但它出现在印度尼西亚语中。
基本上(基于我的例子)
SELECT ... WHERE IN (...)
一起使用时确保它不包含重复行,您可以通过在两个字段上使用主键来阻止它,或使用{{ 1}} distinct
进行过滤,其中出现次数与我们正在过滤的标记数量相等。很抱歉,如果我的解释不清楚。希望这会有所帮助。