2013-08-22 197 views
0

在我的MySQL数据库中,我有用于从任何人如何按行分组但按最近日期分组?

id    int(11)   id of the message  
from member_id int(11)   id of the person the message was sent from 
to member_id  int(11)   id of the person the message was sent to 
date sent  datetime   date of when it was sent 
active   tinyint(1)  if the message is deleted  
text    longtext   the text of the message 
from_read  tinyint(1)  boolean to know if the person who sent it read it 
to_read   tinyint(1)  boolean to know if the person who it got sent to read it 

因此,例如,存储的谈话的消息像这样的表,它可以像:

from_member_id to_member_id date sent 
1    2   june 12 
1    3   june 13 
2    3   june 14 
3    1   june 9 

所以我们的人之间的对话12,13,23

我试图得到一个select语句,这将给我当前用户是从每一个用户在谈话中涉及到的最新消息。因此,如果1在随后登录我希望拿到2行。结果集中的第一行将是上面的第二行(7月13日),因为它是最近的,然后结果集中的第二行将是上面的第一行(6月12日),这是最近从1两次谈话。结果集也需要按发送日期排序,因此较新的对话列在最上面。

我想要做的就像是Android手机中的短信,您可以在其中看到对话列表以及每个列表中最近的消息。

这是我的SQL查询

SELECT * 
FROM (
    SELECT * 
    FROM  message 
    WHERE `from member_id`=1 OR `to member_id`=1 
    ORDER BY IF(`from member_id`=1, `to member_id`, `from member_id`) 
) as t 
GROUP BY IF(`from member_id`=1, `to member_id`, `from member_id`) 

我只是硬编码1现在是当前用户。我正在做的是,按照我可以使用if语句检查的其他人的ID对它们进行排序,然后对结果进行分组,以便尝试从每个对话中获取最近的一个。

问题是,在分组时,每个组可能有多于一行,而它似乎只是选择一些随机行。我如何才能选择具有最新日期发送值的行?

回答

2

你在找这样的事吗?

SELECT m.* 
    FROM message m JOIN 
(
    SELECT from_member_id, to_member_id, MAX(date_sent) date_sent 
    FROM message 
    WHERE from_member_id = 1 
    GROUP BY from_member_id, to_member_id 
) q 
    ON m.from_member_id = q.from_member_id 
    AND m.to_member_id = q.to_member_id 
    AND m.date_sent = q.date_sent 
ORDER BY date_sent DESC 

输出示例:

 
| FROM_MEMBER_ID | TO_MEMBER_ID | DATE_SENT | 
---------------------------------------------- 
|    1 |   3 | 2013-06-13 | 
|    1 |   2 | 2013-06-12 | 

这里是SQLFiddle演示

UPDATE

SELECT m.* 
    FROM message m JOIN 
(
    SELECT LEAST(from_member_id, to_member_id) least_id, 
     GREATEST(from_member_id, to_member_id) greatest_id, 
     MAX(date_sent) date_sent 
    FROM message 
    WHERE from_member_id = 1 
     OR to_member_id = 1 
    GROUP BY LEAST(from_member_id, to_member_id), 
      GREATEST(from_member_id, to_member_id) 
) q 
    ON LEAST(m.from_member_id, m.to_member_id) = q.least_id 
    AND GREATEST(m.from_member_id, m.to_member_id) = q.greatest_id 
    AND m.date_sent = q.date_sent 
ORDER BY date_sent DESC 

输出示例:

 
| FROM_MEMBER_ID | TO_MEMBER_ID | DATE_SENT | 
---------------------------------------------- 
|    3 |   1 | 2013-06-14 | 
|    1 |   2 | 2013-06-12 | 

这里是SQLFiddle演示

+0

这工作时,最新的消息是从当前用户。但它不考虑从其他用户发送给当前用户的消息。 – omega

+0

@omega查看可能的解决方案的更新答案 – peterm

+0

@omega它有帮助吗? – peterm

0
SELECT 
    * 
FROM message m INNER JOIN 
    (
    SELECT 
     from_menber_id, 
     MAX(date_sent) AS sentdate 
    FROM message s 
    GROUP BY from_menber_id 
) AS a 
    ON m.date_sent = a.sentdate AND a.from_menber_id = m.from_menber_id 
+0

什么是样本? – omega

+0

对不起,这是表的名称。我编辑过它。请看看这是你需要的。 – Nisha