A maneira mais simples é com
not exists ou left join :select u.*
from users u left join
addresses a
on a.username = u.username and
a.city = 'Peoria'
where a.city is null;
A
left join mantém todos os registros em usuários e quaisquer registros em addresses que correspondem ao on condições. Neste caso (porque o nome da cidade está no on condição), ele retorna todos os usuários com informações sobre as cidades ou NULL valores. O where cláusula escolhe o NULL valores -- os não correspondentes. O equivalente
not exists pode ser mais fácil de seguir:select u.*
from users u
where not exists (select 1
from addresses a
where a.username = u.username and
a.city = 'Peoria'
);