Pensa a cosa sta facendo il tuo codice logicamente:
( 1 IN (tag.tag_id) ) AND ( 2 IN (tag.tag_id) )
è equivalente a
( 1 = (tag.tag_id) ) AND (2 = (tag.tag_id) )
Non c'è modo tag.tag_id
può soddisfare entrambe le condizioni contemporaneamente, quindi AND non è mai vero.
Sembra che la versione OR che hai citato nella tua domanda sia quella che desideri davvero:
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 clausola IN in modo più appropriato, potresti scriverla come:
SELECT DISTINCT name FROM person LEFT JOIN tag ON person.id = tag.person_id
WHERE tag.tag_id in (1,2);
Un'ultima nota, perché stai facendo riferimento a una colonna della tabella LEFT JOINed nella tua clausola WHERE (tag.tag_id
), lo stai davvero costringendo a comportarsi come un INNER JOIN. Per ottenere veramente un LEFT JOIN, dovresti spostare i criteri da WHERE e renderlo invece parte delle condizioni JOIN:
SELECT DISTINCT name FROM person LEFT JOIN tag ON person.id = tag.person_id
AND tag.tag_id in (1,2);