Piensa en lo que tu código está haciendo lógicamente:
( 1 IN (tag.tag_id) ) AND ( 2 IN (tag.tag_id) )
es equivalente a
( 1 = (tag.tag_id) ) AND (2 = (tag.tag_id) )
De ninguna manera tag.tag_id
puede satisfacer ambas condiciones al mismo tiempo, por lo que AND nunca es verdadero.
Parece que la versión OR que citó en su pregunta es la que realmente desea:
SELECT DISTINCT name FROM person LEFT JOIN tag ON person.id = tag.person_id
WHERE ( ( 1 IN (tag.tag_id) ) OR ( 2 IN (tag.tag_id) ) );
Usando la cláusula IN de manera más apropiada, podría escribirlo como:
SELECT DISTINCT name FROM person LEFT JOIN tag ON person.id = tag.person_id
WHERE tag.tag_id in (1,2);
Una nota final, porque está haciendo referencia a una columna de la tabla LEFT JOINed en su cláusula WHERE (tag.tag_id
), realmente estás obligando a que se comporte como una UNIÓN INTERNA. Para obtener realmente un LEFT JOIN, debe mover los criterios fuera de DONDE y hacerlo parte de las condiciones de JOIN en su lugar:
SELECT DISTINCT name FROM person LEFT JOIN tag ON person.id = tag.person_id
AND tag.tag_id in (1,2);