2013-12-18 6 views
0

У меня есть 3 таблицы для системы чата:Найти строку на основе набора иностранных строк

  1. разговор эта таблица содержит идентификатор и временную метку
  2. conversation_participant говорит мне, какие пользователи в чат
  3. conversation_message сообщения отправить в чат (также имеет sender_id)

Эта настройка работает неплохо для меня, но теперь я хочу сделать «обратный» поиск. Я знаю, какие пользователи собираются начать новый чат, и я хочу знать, имеет ли эта конкретная группа разговор в БД. Есть ли способ найти строку на основе динамического набора иностранных строк?

(желательно без поворота, как уловки)

Или моя структура базы данных несовершенна и я должен изменить это?

CONVERSATION 
    id int auto_increment 
    start timestamp 

CONVERSATION_PARTICIPANT 
    conversation_id int (foreign key to conversation) 
    participant_id int (foreign key to users table) 

CONVERSATION_MESSAGE 
    id int auto_increment 
    conversation_id int (foreign key to conversation) 
    author_id int 
    time timestamp 
    message text 
+0

Если у вас есть набор пользователей, которые хотят общаться, вы хотите найти разговор, в котором было по крайней мере два из них, или все из них? Если бы между четырьмя людьми и тремя часами обсуждался разговор, следует ли выбирать этот разговор, хотя 1 человека там нет? Должен ли он быть самым последним разговором? – AgRizzo

+0

Он должен соответствовать только одному и тому же набору пользователей. Поэтому 3 человека, которые были в чате 4 раньше, должны начать новый разговор. Это самый последний разговор не имеет значения, поскольку для каждого точного набора пользователей должен быть только один разговор. –

ответ

1

Это предполагает, что вы:

  • есть список разделенных запятыми participant_id х -> список $
  • знать количество участников -> $ Кол
  • использовать один из участников WHERE -> $ участник

заменить эти псевдопеременные на реальные значения

Вы можете увидеть код здесь: http://sqlfiddle.com/#!2/e90f2/11

Код:

SELECT conversation_participant.conversation_id AS conversation_id 
    , SUM(IF(members.participant_id IN ($list),1,0)) AS member_count 
    , COUNT(*) AS total 
FROM conversation_participant 
JOIN conversation_participant AS members 
    ON members.conversation_id = conversation_participant.conversation_id 
WHERE conversation_participant.participant_id = $participant 
GROUP BY conversation_id 
HAVING member_count = total 
    AND member_count = $qty; 

FYI: Цель ИНЕКЕ, чтобы ограничить число потенциальных разговоров.

+0

Это великолепно! Вы даже приняли во внимание, что в списке может быть больше пользователей. Благодаря! –

Смежные вопросы