Вы делаете распространенную ошибку при проектировании базы данных, сохраняя разделенный запятыми список идентификаторов тегов. Неудивительно, что выполнение эффективных запросов против этого блокирует вас.
Вам нужно смоделировать сопоставление между объектами и тегами в отдельной таблице.
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)
);
Вставьте одну строку для каждой пары объект / тег. Конечно, это означает, что у вас есть несколько строк для каждого object_id
, но это нормально.
Вы можете запросить все объекты с тегами 3,4,5:
SELECT DISTINCT object_id
FROM Tagged
WHERE tag_id IN (3, 4, 5);
Но это соответствует object1, который вам не нужен. Вы хотите исключить объекты, у которых есть другие теги, кроме 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;