Группировка По / Потоковые Сообщения MySQL Prob

0

Я создаю частную систему обмена сообщениями для сайта знакомств. У меня проблемы с группой по запросу. Вот структура таблицы:

`id` bigint (20) NOT NULL AUTO_INCREMENT , 
`fromme` integer (11) NOT NULL, 
`tome` integer (11) NOT NULL, 
`subject` varchar (255) NOT NULL, 
`message` longtext NOT NULL, 
`mydate` datetime NOT NULL, 
`thread` varchar (255) NOT NULL, 
`receipt` varchar (50) NOT NULL, 
`INDELETE` varchar (5), 
`SENTDELETE` varchar (5),
PRIMARY KEY (`id`)

Когда пользователь отправляет новое сообщение другому пользователю, он генерирует случайную строку для отслеживания потока. Как они отвечают, он несет строку нити (похожую на facebook). Когда пользователь входит в систему, они могут видеть все сообщения в своем почтовом ящике и в зависимости от того, является ли это новым сообщением, он изменяет цвет bg строки. Все это работает нормально, за исключением статуса получения сообщения, которое было вложено туда и обратно. Это запрос:

select messages.id, messages.fromme, messages.subject, messages.message, messages.receipt, messages.mydate, messages.thread, users.firstname, users.lastname, users.image1
from messages, users
where messages.tome = '40' and messages.INDELETE !='y' and messages.fromme = users.id
GROUP BY messages.thread
ORDER BY messages.mydate desc

Он возвращает его правильно, но группа по функции возвращает сообщение FIRST потока. Мне нужен ПОСЛЕДНИЙ, чтобы он работал правильно. Кто-нибудь знает, как это сделать?

Теги:
greatest-n-per-group

2 ответа

1
Лучший ответ

Чтобы получить преимущество предложения GROUP BY, вам нужна сводная функция (MAX, SUM, COUNT и т.д.). Вероятно, вы захотите использовать этот подзапрос, чтобы выработать последнее сообщение (самый высокий ID) в каждом потоке:

select MAX(messages.id) id, messages.thread 
FROM messages
GROUP BY messages.thread

Объединяя все это, вы можете использовать

SELECT messages.id, 
       messages.fromme, 
       messages.subject, 
       messages.message, 
       messages.receipt, 
       messages.mydate, 
       messages.thread, 
       users.firstname, users.lastname, users.image1
  FROM messages, 
       users,
       (SELECT MAX(messages.id) id, messages.thread thread 
          FROM messages
        GROUP BY messages.thread) latest,
 WHERE messages.tome = '40' 
   AND messages.INDELETE !='y' 
   AND messages.fromme = users.id
   AND messages.id=latest.id
ORDER BY messages.mydate desc
2

Ответ @Ollie Jones в порядке (за исключением устаревшего синтаксиса соединения в стиле запятой SQL-89), но для чего он стоит здесь:

SELECT m1.*, u.*
FROM messages m1
LEFT OUTER JOIN messages m2
  ON (m1.thread=m2.thread AND m1.mydate < m2.mydate)
JOIN users u ON (m1.fromme = u.id)
WHERE m2.thread IS NULL;

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

Это решение подходит для MySQL, потому что MySQL обычно создает временную таблицу, сортируя запросы GROUP BY. Решение соединения часто выполняется быстрее. Убедитесь, что у вас есть индекс (thread, mydate).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню