2014-12-28 1 views
0

Например, если у меня есть эта таблица сообщений и имеет эти 3 колонкиКак выбрать уникальное сочетание 2-х столбцов в MYSQL

╔══════════╦══════════╦══════════╦══════════╦ 
║ from_user║ to_user ║ message ║ date ║ 
╠══════════╬══════════╣══════════║══════════║ 
║ 1  ║ 2  ║ text  ║timestamp ║ 
║ 1  ║ 3  ║ text  ║ ..  ║ 
║ 2  ║ 1  ║ text  ║ ..  ║ 
║ 2  ║ 3  ║ text  ║ ..  ║ 
║ 3  ║ 1  ║ text  ║ ..  ║ 
║ 1  ║ 2  ║ text  ║ ..  ║ 
║ 1  ║ 4  ║ text  ║ ..  ║ 
║ 3  ║ 1  ║ text  ║ ..  ║ 
╚══════════╩══════════╩══════════╩══════════╩ 

Я хочу, чтобы получить все, где пользователь участвует, если я хотел выбрать все разговоры пользователей 1 была (все записи, где он находится в в колонке «от _user» и где он находится в «to_user) это„разговоры“было бы:

  1. диалог между пользователем 1 и 2
  2. диалог между пользователем 1 и 3
  3. диалог между пользователем 1 и 4

Так я хотел бы получить только 1 запись (последний) каждый из этих разговоров упорядоченных по дате

╔══════════╦══════════╦══════════╦══════════╦ 
║ from_user║ to_user ║ message ║ date ║ 
╠══════════╬══════════╣══════════║══════════║ 
║ 1  ║ 2  ║ text  ║timestamp ║ 
║ 1  ║ 3  ║ text  ║ ..  ║ 
║ 2  ║ 1  ║ text  ║ ..  ║ 
║ 2  ║ 3  ║ text  ║ ..  ║ 
║ 3  ║ 1  ║ text  ║ ..  ║ 
║ 1  ║ 2  ║ text  ║ ..  ║<--- i would get this one third (conv between 1&2) 
║ 2  ║ 3  ║ text  ║ ..  ║ 
║ 1  ║ 4  ║ text  ║ ..  ║<--- i would get this one second (conv between 1&4) 
║ 3  ║ 1  ║ text  ║ ..  ║<--- i would get this one first (conv between 1&3) 
╚══════════╩══════════╩══════════╩══════════╩ 

Я не уверен относительно того, как решить это, я должен использовать GROUP BY?

EDIT: разговор, когда пользователь отправляет или получает сообщение, разговор может содержать несколько сообщений или только один. Те, что я отметил, что я хотел получить результат, - это последняя запись каждой из этих бесед, неважно, кто ее отправил и кто ее получил. Я хочу, чтобы последняя запись каждого из разговоров была у пользователя.

Эта попытка ближе я могу получить то, что я хочу

SELECT id, from_user, to_user 
FROM messages 
WHERE (to_user = '$usr_id' OR from_user = '$usr_id') AND id IN 
(
    SELECT MAX(id) 
    FROM messages 
    GROUP BY from_user, to_user 
) 

, но я получаю последнюю запись каждого из комбинаций, например, если у

id from_user to_user 
1  1   2 
2  1   3 
3  4   1 
4  2   1 
5  1   2 

выход это:

id from_user to_user 
1  1   2 
2  1   3 
3  4   1 
4  2   1 

Как вы можете видеть, запись с идентификатором 5 не выбрана, поскольку она повторяется, но записи с идентификаторами 1 и 4 - это один и тот же разговор, и только один из них должен быть отправлен

+2

уточните: порядок, отображаемый в последней таблице, основан на дате, которая отсутствует в таблице или каких-либо других критериях? что происходит с (1,3) и (2,1)? они встречаются только один раз. nd (2,1) встречается дважды, но вы его выбрали ... – koriander

+0

Рассмотрите возможность предоставления надлежащих DDL и желаемого результата. – Strawberry

+0

Я добавил столбец для даты, не имеет значения, сколько раз они происходят, как объяснено в редактировании. Что значит, я выбрал его? –

ответ

1

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

SELECT from_user, to_user, max(msg_date) latest, id 
FROM  messages 
WHERE to_user = 1 
     OR from_user = 1 
GROUP BY from_user, to_user 
ORDER BY latest desc; 

чтобы получить это решается с помощью группы по, вам нужно переключить from_user, значения столбцов to_user, когда ваш пользователь находится на стороне to_user. Вам также может понадобиться флаг, «переключенный», чтобы указать эти случаи. Итак, что вам нужно:

SELECT id, main_user, other_user, switched, max(msg_date) latest, msg_date, msg 
FROM (SELECT id, 1 main_user, if (from_user = 1, to_user, from_user) other_user, 
       if (from_user=1, 0, 1) switched, msg_date, msg 
     FROM messages 
     WHERE to_user = 1 
      OR from_user = 1) user_messages 
GROUP BY main_user, other_user 
ORDER BY msg_date desc; 

В этом же запросе, вы можете использовать «переключился» положить обратно from_user, to_user, используя IF, как в подзапроса. Я не ставил его сейчас, чтобы было легче читать.

+0

Я прояснил некоторые вещи и исправил несколько других. В основном я хочу выбрать все разговоры, в которых участвует конкретный пользователь. –

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