2014-10-28 3 views
-2

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

CREATE TABLE IF NOT EXISTS message(
    message_id BIGINT(20) NOT NULL AUTO_INCREMENT, 
    from_id BIGINT(20) NOT NULL, 
    to_id BIGINT(20) NOT NULL, 
    message varchar(3000), 
    mesaging_topic BIGINT(20), 
    create_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP, 
    PRIMARY KEY(message_id) 
); 

ALTER TABLE message 
    ADD CONSTRAINT message_fk1 FOREIGN KEY(from_id) REFERENCES user(id), 
    ADD CONSTRAINT message_fk2 FOREIGN KEY(to_id) REFERENCES user(id), 
    ADD CONSTRAINT message_fk3 FOREIGN KEY(messaging_topic) REFERENCES messaging_topic(messaging_topic_id); 

Мне нужно найти список первых 10 разговоров с конкретным пользователем в порядке убывания create_date, а другой пользователь не должен повторяться в результате. Результат должен быть похож на то, что мы видим в сообщениях Facebook.

+0

http://dev.mysql.com/doc/refman/5.0/en/select.html – David

+0

@David Я не прошу простого запроса. Я ищу только первый разговор с другим пользователем, и это тоже порядок create_date. Точно так же, как то, что мы видим в сообщениях facebook, где мы видим только последний разговор с каждым пользователем –

+0

@hiteshjain OP, вы хотите, чтобы последние 10 сообщений были у пользователя независимо от того, с кем они были, или вы хотите последние 10 человек? Когда вы ссылаетесь на сообщение facebook, вы имеете в виду, как маленький быстрый просмотр, где он показывает последнее сообщение в моих 10 самых последних разговорах? – AdamMc331

ответ

-1

предположим, что зафиксированная пользователь 20

SELECT `message_id`, IF(`from_id` = 20, `to_id`, `from_id`) AS `anotheruser`, 
IF(`from_id` = 20,`from_id`, `to_id`) AS `me`, `to_id`, `message`, `mesaging_topic` 
FROM `message` 
WHERE (`from_id` = 20 OR `to_id` = 20) 
GROUP BY `anotheruser` ORDER BY `create_date` DESC LIMIT 0,10 
+0

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

0

Основываясь на моем неправильном предположении, я решил стереть мой ответ и дать вам новую. Эта проблема была очень сложной.

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

(SELECT from_id, MAX(create_date) AS latestMessage 
FROM message 
WHERE to_id = 1 
GROUP BY from_id) 
UNION 
(SELECT to_id, MAX(create_date) AS latestMessage 
FROM message 
WHERE from_id = 1 
GROUP BY to_id) 

В то время как я сделал это, я получил максимальную дату в качестве последнего сообщения для каждой пары, группировка по ид.

Однако этого все еще недостаточно. Он вытащит последнее сообщение от пользователя 1-> 2, а также последнее сообщение от пользователя 2-> 1. Теперь выше не используется идентификатор пользователя 1, а только пользователи, с которыми они взаимодействовали. Таким образом, я вложил это в другой запрос, который взял максимальную дату для групп выше, чтобы получить последнюю дату сообщения от пользователей 1 и 2 независимо от того, кто ее отправил. Это привело меня сюда:

SELECT from_id, MAX(latestMessage) AS latestMessageBetweenUsers 
FROM((SELECT from_id, MAX(create_date) AS latestMessage 
    FROM message 
    WHERE to_id = 1 
    GROUP BY from_id) 
    UNION 
    (SELECT to_id, MAX(create_date) AS latestMessage 
    FROM message 
    WHERE from_id = 1 
    GROUP BY to_id)) t 

Теперь у меня есть для каждого пользователя, что пользователь # 1 послал сообщения с, и дата последнего сообщения. Затем я взял это и присоединился к нему с нашей исходной таблицей при условии, что идентификатор сверху был равен одному из идентификаторов в исходной таблице и что дата даты совпадает. Мне также пришлось снова фильтровать user_id 1. Я отсортировал по дате нисходящего сообщения и использовал предложение LIMIT, чтобы получить 10 последних.

Вот окончательный запрос:

SELECT * 
FROM message m 
JOIN(SELECT from_id, MAX(latestMessage) AS latestMessageBetweenUsers 
    FROM((SELECT from_id, MAX(create_date) AS latestMessage 
    FROM message 
    WHERE to_id = 1 
    GROUP BY from_id) 
    UNION 
    (SELECT to_id, MAX(create_date) AS latestMessage 
    FROM message 
    WHERE from_id = 1 
    GROUP BY to_id)) t 
GROUP BY from_id) t 
ON (t.from_id = m.from_id OR t.from_id = m.to_id) AND m.create_date = t.latestMessageBetweenUsers 
WHERE m.from_id = 1 OR m.to_id = 1 
ORDER BY t.latestMessageBetweenUsers DESC 
LIMIT 10; 

А вот рабочий SQL Fiddle. Конечно, я использовал только данные образца, пожалуйста, проверьте в своей базе данных и вернитесь ко мне.

+0

Это может привести к разговору между двумя пользователями более одного раза. Мне нужен только последний разговор между двумя пользователями в результирующем наборе. –

+0

@hiteshjain Я, наконец, решил это. Мой класс только начался - я сообщу вам, когда смогу изменить свой ответ. – AdamMc331

+0

@hiteshjain см. Мое редактирование. Это была отличная проблема, и она очень стимулировала мозг. – AdamMc331

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