Reputation: 15217
I'm trying to search for all posts for a specific tag name, whilst still being able to join all tags for the returned posts.
id
...
id
name
slug
id
post_id
tag_id
I'll do a query such as this:
SELECT * FROM posts p
INNER JOIN posts_tags pt ON pt.post_id = p.id
INNER JOIN tags t ON pt.tag_id = t.d
WHERE t.slug = 'foo'
This will return me all posts with the tag foo
, but will no longer join the other tags associated with the posts. How can I write it in such a way so I can still get all tags on the posts?
For example, say I have a post which has 3 tags associated with it: cat
, dog
and chimp
. I want to do a query for posts which have the tag dog
. How can I construct a query which will fetch me the posts with the tag dog
, ensuring that the cat
and chimp
tags are also retrieved in the result?
Upvotes: 0
Views: 563
Reputation: 133400
if you need all the tags slug related to post that are related to foo then you could use
select distinct tags.slug
from tags
inner join (
SELECT post_id from posts_tags pt
INNER JOIN tags t ON pt.tag_id = t.d
WHERE t.slug = 'foo'
) t on t.id = post_tags.post_id
inner join tags on tags.id = post_tags.tag_id
or if you need the related post too
select post.*, tags.slug
from tags
inner join (
SELECT post_id from posts_tags pt
INNER JOIN tags t ON pt.tag_id = t.d
WHERE t.slug = 'foo'
) t on t.id = post_tags.post_id
inner join tags on tags.id = post_tags.tag_id
inner join post on post.id = post_tag.post_id
Upvotes: 0
Reputation: 1271003
If you want all the posts that have 'foo' as a tag, then you need more complicated logic. For your purposes, I think it is probably sufficient to get the tags as a delimited list:
SELECT p.*, GROUP_CONCAT(t.slug) as tags
FROM posts p INNER JOIN
posts_tags pt
ON pt.post_id = p.id INNER JOIN
tags t
ON pt.tag_id = t.d
GROUP BY p.id
HAVING SUM(t.slug = 'foo') > 0;
Upvotes: 0
Reputation: 5135
If you want all the tags for all the posts which include foo
as well as all other tags, then i think you can do a left join.
SELECT * FROM posts p
INNER JOIN posts_tags pt ON pt.post_id = p.id
LEFT JOIN tags t
ON pt.tag_id = t.d
Above will give you all the posts and the relevant tags for the posts. You can order by slug
OR you can add a clause with left join to filter by tag you need like below:
SELECT * FROM posts p
INNER JOIN posts_tags pt ON pt.post_id = p.id
LEFT JOIN tags t
ON pt.tag_id = t.d AND t.slug IN ('foo') --add other tags if needed
Upvotes: 1