La differenza è che quando usi exists
- la query all'interno di solito dipende dalla query principale (mean usa colonne da essa e quindi non può essere eseguita separatamente) e, quindi, per ogni riga della query principale controlla se alcuni dati recuperati dalla sottoquery esistono o meno.
Il problema della tua prima query è che la sottoquery all'interno del blocco esiste non dipende comunque dalle colonne principali della query, è una query separata che restituisce sempre una riga con 1
, quindi, per ogni riga della query principale il risultato di exists
sarà sempre true
. Quindi, la tua prima query equivale a
SELECT distinct(company_id)
FROM user
WHERE user.user_id = 123
AND user.company_id IS NOT NULL
Vedi anche violino