RhodiumToad на # postgresql @ freenode ответил:
Хотите результат как (user_id, has_hat)
? Или просто список пользователей с шляпами или пользователей без шляп? Или один истинный / ложный результат для «У кого-нибудь есть шляпа?»
Наиболее эффективным ответом на различные вопросы будет ответ на первый вопрос:
select exists(
select 1
from users u
where not exists(
select 1
from hats h
where h.user_id=u.id));
Это потому, что (а) это можно планировать как анти-объединение и (б) останавливается в первом матче. Есть еще одно преимущество: буквально говорится: «существует ли пользователь таким, что для него нет шляпы», так что это должно быть легко понять будущим читателям.
Следующим лучшим вариантом, если вы хотите больше подробностей, является средний вариант (пользователи с / без шляп), например:
- показывает всех пользователей хотя бы с одной шляпой
Выбрать *
от пользователей
где существует (
выберите 1
из шапки ч
где h.user_id = u.id);
-- shows all users with no hat
select *
from users u
where not exists(
select 1
from hats h
where h.user_id=u.id);
Первый вариант не так эффективен, поэтому его следует избегать:
-- shows all users, with a flag for whether they have a hat
select u.id, exists(
select 1
from hats h
where h.user_id=u.id) as has_hat
from users u;