SQL-запрос хотя бы одного из чего-либо - PullRequest
11 голосов
/ 07 июля 2010

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

Users: id
Posts: user_id, rating

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

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

Спасибо!

Ответы [ 6 ]

22 голосов
/ 07 июля 2010

Чтобы найти всех пользователей с хотя бы одним постом с рейтингом выше 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, где совпадают значения идентификатора, в дополнение к сравнению рейтинга.

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

2 голосов
/ 07 июля 2010

Вы можете объединить таблицы, чтобы найти соответствующих пользователей, и использовать 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
1 голос
/ 08 июля 2010
select distinct id
from users, posts
where id = user_id and rating > 10
1 голос
/ 07 июля 2010

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

SELECT * from users INNER JOIN posts p on users.id = p.user_id where p.rating > 10;
0 голосов
/ 07 июля 2010

Правильный ответ на ваш вопрос, как указано, является ответом OMG Ponies, ГДЕ СУЩЕСТВУЕТ, является более информативным и почти всегда быстрее.Но «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 голосов
/ 07 июля 2010
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;

Кроме того, это скажет вам, какой у них самый высокий рейтинг.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...