Você está cometendo um erro comum em design de banco de dados, armazenando uma lista separada por vírgulas de etiqueta de identificação da. Não é uma surpresa que a realização de consultas eficientes contra esse é um bloqueador para você.
O que você precisa é modelar o mapeamento entre objetos e tags em uma tabela separada.
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)
);
Inserir uma linha para cada emparelhamento objeto / tag. Claro, isso significa que você tem várias linhas para cada object_id, mas tudo bem.
Você pode consultar todos os objetos que têm etiquetas 3,4,5:
SELECT DISTINCT object_id
FROM Tagged
WHERE tag_id IN (3, 4, 5);
Mas isso corresponde object1, que você não quer. Você quer excluir objetos que têm outras tags não em 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;