I have a photos
table, a tags
table, and a bridge table called photos_tags
. Imagine there's a photo which has been tagged with dog
, cat
, and bird
. This means that there'll be 1 row in photos
, 1 row in tags
, and 3 rows in photos_tags
.
I'm trying to write an SQL statement to fetch all 3 tags if one of them matches. I've gotten this far:
select distinct p.photo_id, t.tag from photos p
join photos_tags pt using (photo_id)
join tags t on pt.tag_id = t.tag_id and t.tag = 'dog'
But this only returns the rows where tag = 'dog'
.
Is there a way to accomplish what I'm trying to do?
First identify all of the photos that have the "dog" tag, which you already did but I'm going to rewrite for the CTE
SELECT photo_id
FROM photos_tags
WHERE tag_id IN (SELECT tag_id FROM tags WHERE tag = 'dog')
Now use this to filter your query to show all tags
for any photo_id
that was surfaced:
WITH dog_photos AS
(
SELECT photo_id
FROM photos_tags
WHERE tag_id IN (SELECT tag_id FROM tags WHERE tag = 'dog')
)
SELECT p.photo_id, t.tag
FROM photos p
INNER JOIN photos_tags pt USING (photo_id)
INNER JOIN tags t ON pt.tag_id = t.tag_id
WHERE p.photo_id IN (SELECT photo_id FROM dog_photos)