Группировка По / Потоковые Сообщения MySQL Prob - PullRequest
0 голосов
/ 20 декабря 2009

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

`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

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

Ответы [ 2 ]

2 голосов
/ 21 декабря 2009

Ответ @ Олли Джонс в порядке (за исключением устаревшего синтаксиса соединения в стиле запятых в 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).

1 голос
/ 21 декабря 2009

Чтобы воспользоваться предложением 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
...