Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql HABTM查询帮助_Mysql_Sql_Has And Belongs To Many_Sql Match All - Fatal编程技术网

Mysql HABTM查询帮助

Mysql HABTM查询帮助,mysql,sql,has-and-belongs-to-many,sql-match-all,Mysql,Sql,Has And Belongs To Many,Sql Match All,“文章”和“标签”之间存在HABTM关系 问题:我只寻找同时带有“sports”和“Outdoor”标签的文章,而不是只带有其中一个标签的文章 我试过这个: SELECT DISTINCT article.id, article.name FROM articles inner JOIN tags ON (tags.name IN ('outdoors', 'sports') inner JOIN articles_tags ON articles_tags.article_id = artic

“文章”和“标签”之间存在HABTM关系

问题:我只寻找同时带有“sports”和“Outdoor”标签的文章,而不是只带有其中一个标签的文章

我试过这个:

SELECT DISTINCT article.id, article.name FROM articles
inner JOIN tags ON (tags.name IN ('outdoors', 'sports')
inner JOIN articles_tags ON articles_tags.article_id = article.id AND articles_tags.tag_id = tags.id
…但它给我的文章只有体育类、户外类和体育+户外类

问题什么是正确的查询?(我正在使用MySQL)

试试这个:

SELECT a1.id, a1.name FROM articles a1
    JOIN tags t1 ON t1.name ='outdoors'
    JOIN articles_tags at1 ON at1.article_id = a1.id AND at1.tag_id = t1.id
    JOIN tags t2 ON t2.name = 'sports'
    JOIN articles_tags at2 ON at2.article_id = a1.id AND at2.tag_id = t2.id

有两种常见的解决方案

  • 第一种解决方案使用
    groupby
    计算每篇文章中与“户外”或“运动”匹配的标签,然后只返回两个标签都有的组

    SELECT a.id, a.name
    FROM articles AS a
    INNER JOIN articles_tags AS at ON (a.id = at.article_id)
    INNER JOIN tags AS t ON (t.id = at.tag_id)
    WHERE t.name IN ('outdoors', 'sports')
    GROUP BY a.id
    HAVING COUNT(DISTINCT t.name) = 2;
    
    对于某些人来说,此解决方案更具可读性,并且添加值更简单。但是MySQL中的
    groupby
    查询往往会产生一个临时表,这会影响性能

  • 另一种解决方案为每个不同的标记使用一个
    JOIN
    。通过使用内部联接,查询自然会限制到与指定的所有标记匹配的项目

    SELECT a.id, a.name
    FROM articles AS a
    INNER JOIN articles_tags AS at1 ON (a.id = at1.article_id)
    INNER JOIN tags AS t1 ON (t1.id = at1.tag_id AND t1.name = 'outdoors')
    INNER JOIN articles_tags AS at2 ON (a.id = at2.article_id)
    INNER JOIN tags AS t2 ON (t2.id = at2.article_id AND t2.name = 'sports');
    
    假设
    tags.name
    articles\u标记(article\u id,tag\u id)
    都有
    UNIQUE
    约束,则不需要
    DISTINCT
    查询修饰符

    假设您已经定义了适当的索引,那么这种类型的查询在MySQL上的优化效果往往优于
    groupby
    解决方案


如果你在评论中提出了后续问题,我会这样做:

SELECT a.id, a.name, GROUP_CONCAT(t3.tag) AS all_tags
FROM articles AS a
INNER JOIN articles_tags AS at1 ON (a.id = at1.article_id)
INNER JOIN tags AS t1 ON (t1.id = at1.tag_id AND t1.name = 'outdoors')
INNER JOIN articles_tags AS at2 ON (a.id = at2.article_id)
INNER JOIN tags AS t2 ON (t2.id = at2.article_id AND t2.name = 'sports');
INNER JOIN articles_tags AS at3 ON (a.id = at3.article_id)
INNER JOIN tags AS t3 ON (t3.id = at3.article_id);
GROUP BY a.id;
这仍然只能找到同时具有“Outdoor”和“sports”标签的文章,但它会进一步将这些文章加入到其所有标签中


这将为每篇文章返回多行(每个标签一行),因此我们使用
groupby
再次将每篇文章减少到一行。返回相应组中以逗号分隔的值列表。

感谢您的解释。。。此外,在该查询中是否可以返回与匹配文章关联的所有标记?