SQL: выберите строки в таблице A, где количество строк в таблице B равно x

#mysql #sql #database

#mysql #sql #База данных

Вопрос:

У меня есть две простые таблицы (база данных MySQL) для приложения чата. Первый — это «Чаты», где хранятся метаданные, такие как заголовок, а второй — «Chat_Users», где хранится информация о том, какой пользователь является участником какого чата. Эта таблица выглядит следующим образом:

Пример данных Chat_User

Теперь мне нужно выбрать идентификаторы чатов, в которых ровно 2 пользователя. Я думал, что это не имеет большого значения, но, к сожалению, я борюсь с этой задачей больше, чем ожидалось. Я уже пробовал подсчитывать строки в «Chat_Users», а затем выбирать только те, где это число равно 2:

 SELECT * 
  FROM Chats
  JOIN Chat_Users 
    on Chat_Users.ID_Chat = Chats.ID 
 WHERE Chat_Users.ID_User = 200001
 GROUP 
    BY Chat_Users.ID_Chat
     , Chat_Users.ID_User
 HAVING COUNT(Chat_Users.ID_Chat) = 2
 

В этом примере запрос использует запрос от пользователя с идентификатором 200001, и ожидаемый результат — вернуть все из строк в «Чате» с идентификаторами 1 и 5. Чат 4 состоит из четырех участников, поэтому его не следует выбирать.

Фактический результат приведенного выше запроса — ничто (пустой ответ), но я не понимаю, почему он не работает. Кажется COUNT(Chat_Users.ID_Chat) , что всегда равно 1 вместо реальных пользователей в конкретном чате.

Любая помощь будет высоко оценена.

Ответ №1:

Если вам нужны ровно два пользователя, то:

 select chat_id
from chat_users
group by chat_id
having count(*) = 2;
 

Если вы хотите, чтобы один из этих пользователей был 200001 , используйте having предложение:

 select chat_id
from chat_users
group by chat_id
having count(*) = 2 and
       max(user_id = 200001) > 0;
 

Комментарии:

1. Большое вам спасибо за ваш ответ. Второй предоставленный вами подход, похоже, работает, но я не понимаю в нем функцию max(). Зачем это нужно?

2. @Flexl . . . По сути, он выполняет совокупное логическое или. Если условие когда-либо принимает значение true, оно возвращает «1».

Ответ №2:

При том способе, которым вы располагаете GROUP BY, вы получите только количество, равное 1.

Измените на это:

 SELECT * FROM Chats
INNER JOIN Chat_Users on Chat_Users.ID_Chat = Chats.ID 
WHERE Chat_Users.ID_User = 200001
GROUP BY Chat_Users.ID_User
HAVING COUNT(Chat_Users.ID_Chat) = 2
 

Комментарии:

1. Спасибо вам за ваш ответ. К сожалению, я уже пробовал это, и это не сработало, потому что оно выдает ошибку «Список ВЫБОРА не входит в предложение GROUP BY и содержит неагрегированный столбец».

2. Вероятно, вам нужно перечислить поля из вашей таблицы чатов в этой ГРУППЕ СЛЕДУЮЩИМ ОБРАЗОМ:

3. Да, я подумал то же самое, но затем вы получаете запрос, опубликованный в вопросе выше, с пустым результатом. Но не берите в голову, похоже, что второй ответ работает просто отлично 🙂