Запрос базы данных для получения последнего сообщения от каждого пользователя (например, сообщения facebook)


Мне нужно получить последнее сообщение между зарегистрированным пользователем и любым пользователем, с которым он когда-либо общался, как в facebook. это будет похоже на facebook.com/messages страница. Вот что я делал до сих пор

База Данных

Пользовательская таблица
- cwid
- имя пользователя
- фамилия и имя
- ссылка на изображение пользователя

Сообщение
- идентификатор
- cwid1 (идентификатор отправителя)
- cwid2 (идентификатор получателя)
- сообщение (содержание сообщения)
- время сообщения (метка времени)
- чтение пользователя (перечисление 'Y' 'N')`

Запрос У вошедшего в систему пользователя есть идентификатор =1

SELECT    
user_table.cwid,    
    message.cwid1,   
    message.cwid2,   
    message.message,   
    message.userread,  
    MAX(message.messagetime),   
    user_table.first_name,   
    user_table.last_name,   
    user_table.user_image_link   
    FROM message   
    INNER JOIN user_table   
    ON message.cwid1 = user_table.cwid   
    WHERE (cwid2="1")   
    GROUP BY cwid1   
    ORDER BY messagetime DESC   

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

SELECT    
user_table.cwid,   
    message.cwid1,     
    message.cwid2,    
    message.message,   
    message.userread,    
    MAX(message.messagetime),   
    user_table.first_name,    
    user_table.last_name,    
    user_table.user_image_link    
    FROM message    
    INNER JOIN user_table    
    ON message.cwid1 = user_table.cwid   
    WHERE (cwid1="1")    
    GROUP BY cwid2    
    ORDER BY messagetime DESC    

Мне нужно, чтобы они были смешаны с разными пользователями и отсортированы по времени сообщения, как сообщения Facebook.Я новичок в MySQL, любая помощь будет очень признательна. Спасибо!

Author: CBroe, 2012-10-26

4 answers

Я еще немного поработал над этим и сделал этот запрос. - В нем перечислены сообщения от недавних пользователей, которые отправили мне сообщение ИЛИ получили от меня сообщение - Он также включает сообщения из группового чата, группы могут быть созданы кем угодно, и любой член группы может пригласить своих друзей - Он также включает флаг "прочитано/непрочитано" для выделения непрочитанных сообщений на интерфейсе.

Это не самый эффективный или элегантный запрос, но он работает. Любых улучшений очень много добро пожаловать

SELECT * 
FROM (
 SELECT * 
FROM (

SELECT * 
FROM (

SELECT users.id,'0' AS groupId, users.name,  users.profilePic,  messages.time,messages.message , 'Y' AS unread 
FROM users
INNER JOIN messages ON messages.userId2 = users.id
WHERE messages.userId1 = '" . $userId . "'
UNION 
SELECT users.id,'0' AS groupId, users.name,users.profilePic, messages.time, messages.message , messages.read AS unread
FROM users
INNER JOIN messages ON messages.userId1 = users.id
WHERE messages.userId2 = '" . $userId . "'
) AS allUsers
ORDER BY TIME DESC
) AS allUsersSorted
GROUP BY id
UNION
select * from(
SELECT '0' AS id, msgGroups.id AS groupId, msgGroups.name, msgGroups.image AS profilePic, IF(userGroupMsg.time IS NULL,userGroups.createdOn,userGroupMsg.time )   AS time,IF(userGroupMsg.message IS NULL,'',userGroupMsg.message ), 'Y' AS unread
FROM msgGroups
LEFT JOIN userGroups ON msgGroups.id = userGroups.groupId
LEFT JOIN userGroupMsg ON msgGroups.id = userGroupMsg.groupId
WHERE userGroups.userId = '" . $userId . "'
ORDER BY time DESC

)AS allUsersSorted
GROUP BY groupId

 )AS allSorted
ORDER BY TIME DESC

Пожалуйста, улучшите, если кто-нибудь может.

 2
Author: Pargat Dhillon, 2013-10-20 10:33:34

Может быть, что-то вроде этого:

SELECT
  DISTINCT m.id, m.cwid1, m.cwid2, m.message, m.userread, m.messagetime,
  u.first_name, u.last_name, u.user_image_link
FROM
  user_table u,
  message m,
  (
    SELECT DISTINCT IF(cwid1 = "1", cwid2, cwid1) AS id
    FROM message
    WHERE "1" IN (cwid1, cwid2)
  ) partner
WHERE
  u.cwid = partner.id
  AND (m.messagetime, m.cwid1, m.cwid2) IN
    (
      SELECT MAX(messagetime), cwid1, cwid2
      FROM message
      WHERE (cwid1, cwid2) IN ((partner.id,"1"),("1",partner.id))
      GROUP BY cwid1, cwid2
    )
ORDER BY m.messagetime DESC

И, пожалуйста, обратите внимание, что все столбцы в предложении FROM, которые не отображаются в агрегатной функции, такой как MAX должны появиться в предложении GROUP BY. MySQL в этом случае не вызывает ошибки, но значения в неагрегатных столбцах являются случайными.

 1
Author: jonas, 2012-10-26 14:18:54

Я бы посмотрел, как Facebook настраивает таблицу FQL для сообщений здесь: https://developers.facebook.com/docs/reference/fql/unified_message . И основывайте архитектуру своего стола на этом.

 0
Author: Jessie Frazelle, 2012-12-11 01:05:21
Try this
select m.* ,u.*
            from
                messages m
                inner join (
                select max(id) as maxid
                from messages
                where messages.list_id = " '. $data['list_id'] .'" 
                group By (if(sender_id > reciever_id,  sender_id, reciever_id)), 
                (if(sender_id > reciever_id,  reciever_id, sender_id))
               ) t1 on m.id=t1.maxid 
 0
Author: kunal, 2016-09-30 14:05:36