Here is my problem: I have two tables connected trough a junction table. I'm using MySQL and PHP (Yii2) on an Apache server, but its just the SQL i need help with.
| Objects | ObjectHasTag | Tag |
|---------------------------------------------|
| - id | -object_id | -id |
| - name | -tag_id | -tag |
I need to create a query that returns objects that is tagged with several tags, and my question is if this is doable with reasonable efficiency as a publicly accessible feature as a query.
Example: find all objects with tags 'tagone', 'tagtwo' and 'tagthree'.
I have one solution that works, and that is to have a 'tags'-column in the Objects-table, with all the tag-names divided by commas. This does not seem like a 'best practice'-kinda solution.
I really appreciate any help you guys can provide!
The SQL for this is relatively straightforward:
SELECT *
FROM Objects o
WHERE 3 = (
SELECT COUNT(DISTINCT t.id)
FROM ObjectHasTag ot
JOIN Tag t ON t.id=ot.tag_id
WHERE o.id = ot.object_id
AND t.tag IN ('tag1', 'tag2', 'tag3')
)
The COUNT(DISTINCT t.id)
joins ObjectHasTag
to Tag
, filters Tag
on the list that you would like to search, and counts the number of distinct tags. In order for the object to be selected, all three items from the IN
list must be present. If you know that ObjectHasTag
cannot contain duplicate tagging, for example, because you have a unique index or a constraint on the table, you can replace COUNT(DISTINCT t.id)
with COUNT(*)
.
The o.id = ot.object_id
condition "connects" the nested query to the object selected from Objects
table.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.