Il modo più semplice è con not exists o 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;
Il left join conserva tutti i record negli utenti e tutti i record negli addresses che corrispondono a on condizioni. In questo caso (perché il nome della città è nel on condizione), restituisce tutti gli utenti con informazioni sulle città o NULL i valori. Il where la clausola sceglie il NULL valori -- quelli non corrispondenti.
L'equivalente not exists potrebbe essere più facile da seguire:
select u.*
from users u
where not exists (select 1
from addresses a
where a.username = u.username and
a.city = 'Peoria'
);