You make a common mistake in database design by keeping a comma-delimited list of tag identifiers. Not surprisingly, making effective requests against this is a blocker for you.
You need to model the mapping between objects and tags in a separate table.
CREATE TABLE Tagged ( object_id INT NOT NULL, tag_id INT NOT NULL, PRIMARY KEY (object_id, tag_id), FOREIGN KEY (object_id) REFERENCES Objects(object_id), FOREIGN KEY (tag_id) REFERENCES Tags(tag_id) );
Insert one line for each pairing of objects / tags. Of course, this means that you have several lines for each object_id , but thatβs good.
You can request all objects with tags 3,4,5:
SELECT DISTINCT object_id FROM Tagged WHERE tag_id IN (3, 4, 5);
But this corresponds to object1 that you do not want. You want to exclude objects that have other tags not in 3,4,5.
SELECT DISTINCT t1.object_id FROM Tagged t1 LEFT OUTER JOIN Tagged t2 ON (t1.object_id = t2.object_id AND t2.tag_id NOT IN (3, 4, 5)) WHERE t1.tag_id IN (3, 4, 5) AND t2.object_id IS NULL;
source share