MYSQL возвращает значение null, когда строк больше, чем значений IN

У меня возникли проблемы с поиском правильного названия для этого.

Я работаю над системой обмена сообщениями с двумя таблицами, одна со всеми разными разговорами (пользователи в разговоре и uid разговора), а другая содержит сообщения между пользователями.

Для каждого разговора я создаю строку для каждого пользователя в разговоре с uid разговора и user_id. В разговорах может быть только 2 пользователя, но и много больше (3,4,5,6 и т.д.)

У меня проблема с оператором SQL, которую я не знаю, как решить. Проблема в том, что когда допустим, что есть разговор между 3 пользователями, после этого допустим, что 2 пользователя хотят начать общаться друг с другом наедине без третьего пользователя. Как я могу заставить оператор SQL ничего не возвращать, когда 2 пользователя уже разговаривают вместе с другими пользователями. Так что я могу добавить 2 новые строки в свою таблицу с их собственными частными talk_id.

таблица conversation_list выглядит так:

|id | user_id| conversation_id|
 -----------------------------
| 1 |       1|               1|
| 2 |       3|               1|
| 3 |       1|               2|
| 4 |       2|               2|
| 5 |       4|               2|

И на данный момент мой код SQL выглядит так:

SELECT *
FROM conversation_list
WHERE user_id IN (user1_id,user_id2)
GROUP BY conversation_id
HAVING COUNT(*) = 2 

person Joris Blanc    schedule 07.06.2012    source источник
comment
Что не так с SQL, который вы сейчас используете?   -  person eggyal    schedule 07.06.2012
comment
как насчет count(*) › 2 ?   -  person Gerrat    schedule 07.06.2012
comment
@Gerrat, если я добавлю COUNT(*) > 2, он ничего не вернет, даже если две строки были только что добавлены, и в этом случае он должен вернуть chat_id ранее вставленной строки.   -  person Joris Blanc    schedule 07.06.2012


Ответы (2)


Правильно ли эта формулировка вашего вопроса:

"Как сделать так, чтобы оператор SQL ничего не возвращал, когда любой из двух пользователей общается с любым другим пользователем"?

...or

"Как сделать так, чтобы оператор SQL возвращал строки ТОЛЬКО тогда, когда эти пользователи НЕ общаются с другими пользователями?"

SELECT conversation_id
FROM conversation_list
WHERE user_id IN (5,6)
AND conversation_id NOT IN (
    SELECT conversation_id from conversation_list where user_id NOT IN (5,6)
)
GROUP BY conversation_id
HAVING COUNT(*) = :nb_users 

Это должно возвращать строки только в том случае, если эти пользователи НЕ общаются с другими пользователями.

person Gerrat    schedule 07.06.2012
comment
Большое спасибо, это работает очень хорошо. Я только что добавил GROUP BY conversation_id HAVING COUNT(*) = :nb_users - person Joris Blanc; 08.06.2012
comment
И это правильный вопрос: как я могу заставить оператор SQL ничего не возвращать, когда любой из двух пользователей находится в разговоре с любыми другими пользователями - person Joris Blanc; 08.06.2012

Давайте посмотрим, правильно ли я понял вашу проблему: вы хотите вернуть conversation_id только в том случае, если вы перечислили все user_id, которые участвуют в этом разговоре?

Если это так, взгляните на мой ответ на этот вопрос. Вы можете думать о беседах как о именованных наборах участников, поэтому conversation_id — это имя набора, а user_id — элементы этого набора. Ответ имеет 3 разных способа сделать это с пояснениями.

Последняя версия, адаптированная к вашей таблице, будет выглядеть примерно так:

SELECT totals.conversation_id
FROM (
    SELECT conversation_id, COUNT(*) count
    FROM conversation_list
    GROUP BY conversation_id
) totals
INNER JOIN (
    SELECT conversation_id, COUNT(*) count
    FROM conversation_list
    WHERE user_id IN (6, 5)
    GROUP BY conversation_id
) matches
ON (totals.conversation_id = matches.conversation_id)
WHERE totals.count = 2 AND matches.count = 2;

Где 6 и 5 — это user_id, а 2 — количество user_id.

Первый подзапрос находит общее количество пользователей в каждой беседе, а второй — количество соответствующих пользователей в каждой беседе. Когда matches.count равно 2, в беседе есть все пользователи, которых мы ищем, а если totals.count также равно 2, в беседе нет дополнительных пользователей.

person Aleksi Torhamo    schedule 07.06.2012