HABTM 查询帮助
我在“文章”和“标签”之间存在 HABTM 关系
问题:我只查找同时带有“运动”和“户外”标签的文章,而不是仅带有其中一个标签的文章。
我尝试了这个:
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)
I have a HABTM relationship between 'articles' and 'tags'
Problem: I'm only looking for articles with BOTH the tag 'sports' and 'outdoors' but not articles with only one of these tags.
I tried this:
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
...but it gets me articles that are in only sports, only outdoors AND both sports + outdoors
Question what is the right query to use? (I'm using MySQL)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
试试这个:
Try this:
有两种常见的解决方案。
第一个解决方案使用
GROUP BY
来计算每篇文章与“outdoors”或“sports”匹配的标签,然后仅返回具有这两个标签的组。此解决方案对于某些人来说似乎更具可读性,并且添加值更直接。但是 MySQL 中的
GROUP BY
查询往往会产生一个临时表,这会损害性能。另一个解决方案对每个不同的标签使用
JOIN
。通过使用内部联接,查询自然会限制为与您指定的所有标签相匹配的文章。假设
tags.name
和articles_tags.(article_id,tag_id)
都具有UNIQUE
约束,则不需要DISTINCT
查询修饰符。假设您已经定义了适当的索引,这种类型的查询在 MySQL 上往往比
GROUP BY
解决方案优化得更好。关于评论中的后续问题,我会这样做:
这仍然只找到同时具有“户外”和“运动”标签的文章,但随后它将这些文章进一步加入到所有其标签中。
这将返回每篇文章的多行(每个标签一个),因此我们然后使用 GROUP BY 再次将每篇文章减少到一行。
GROUP_CONCAT()
返回相应组中的值的逗号分隔列表。
There are two common solutions.
The first solution uses
GROUP BY
to count the tags per article that match 'outdoors' or 'sports' and then returns only the groups that have both tags.This solution appears more readable to some people, and adding values is more straightforward. But
GROUP BY
queries in MySQL tend to incur a temporary table which harms performance.The other solution uses a
JOIN
per distinct tag. By using inner joins, the query naturally restricts to articles that match all the tags you specify.Assuming
tags.name
andarticles_tags.(article_id,tag_id)
both haveUNIQUE
constraints, you shouldn't need aDISTINCT
query modifier.This type of query tends to optimize better on MySQL than the
GROUP BY
solution, assuming you have defined appropriate indexes.Re your followup question in the comment, I would do something like this:
This still only finds articles that have both tags 'outdoors' and 'sports', but then it further joins these articles to all its tags.
This will return multiple rows per article (one for each tag) so we then use
GROUP BY
to reduce down to a single row per article again.GROUP_CONCAT()
returns a comma-separated list of the values in the respective group.