SQL-запрос по крайней мере одно из чего-то

У меня есть набор Пользователей, у каждого из которых есть много Сообщений. Схема:

Users: id
Posts: user_id, rating

Как я нахожу всех Пользователей, у которых есть по крайней мере одно сообщение с оценкой выше, скажем, 10?

Я не уверен, должен ли я использовать подзапрос для этого, или если существует более легкий путь.

Спасибо!

12
задан OMG Ponies 7 July 2010 в 23:04
поделиться

6 ответов

Чтобы найти всех пользователей, у которых есть хотя бы одно сообщение с рейтингом выше 10, используйте:

SELECT u.*
  FROM USERS u
 WHERE EXISTS(SELECT NULL
                FROM POSTS p
               WHERE p.user_id = u.id
                 AND p.rating > 10)

EXISTS не заботится об операторе SELECT. внутри него - вы можете заменить NULL на 1/0, что должно привести к математической ошибке при делении на ноль ... Но этого не произойдет, потому что EXISTS касается только фильтрации в предложении WHERE.

Корреляция (WHERE p.user_id = u.id) - это то, почему это называется коррелированным подзапросом и будет возвращать только те строки из таблицы USERS, где значения id совпадают, в дополнение к сравнению рейтингов.

EXISTS также быстрее, в зависимости от ситуации, потому что он возвращает истину, как только критерии соблюдены - дубликаты не имеют значения.

23
ответ дан 2 December 2019 в 05:39
поделиться

Правильным ответом на ваш вопрос, как указано, является ответ OMG Ponies, WHERE EXISTS более описателен и почти всегда быстрее. Но "SELECT NULL" выглядит очень уродливо и нелогично, на мой взгляд. Я видел SELECT * или SELECT 1 в качестве лучшей практики для этого.

Другой способ, на случай, если мы собираем ответы:

SELECT u.id 
FROM users u 
     JOIN posts p on u.id = p.user_id
WHERE p.rating > 10
GROUP BY u.id
HAVING COUNT(*) > 1

Это может быть полезно, если вы тестируете не всегда 1.

0
ответ дан 2 December 2019 в 05:39
поделиться

Используйте внутреннее соединение:

SELECT * from users INNER JOIN posts p on users.id = p.user_id where p.rating > 10;
1
ответ дан 2 December 2019 в 05:39
поделиться

Вы можете присоединиться к таблицам, чтобы найти соответствующих пользователей, и использовать DISTINCT, чтобы каждый пользователь попадал в результирующий набор не более одного раза, даже если у них есть несколько сообщений с рейтингом> 10:

select distinct u.id,u.username
from users u inner join posts p on u.id = p.user_id 
where p.rating > 10
2
ответ дан 2 December 2019 в 05:39
поделиться
select distinct id
from users, posts
where id = user_id and rating > 10
1
ответ дан 2 December 2019 в 05:39
поделиться
SELECT max(p.rating), u.id 
  from users u 
INNER JOIN posts p on users.id = p.user_id 
where p.rating > 10 
group by u.id;

Кроме того, здесь вы узнаете, какой у них самый высокий рейтинг.

0
ответ дан 2 December 2019 в 05:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: