MySQL Select语句 - 用于消息

时间:2009-07-30 21:57:09

标签: php mysql select

我目前有一个私人消息论坛的表格:

alt text http://img159.imageshack.us/img159/45/pmdata.jpg

alt text http://img504.yfrog.com/img504/3968/pminfo.jpg

我要做的是输出一个“收件箱”,它显示最顶层的线程并按线程分组(意思是,你的收件箱中没有看到相同的线程两次),无论是谁发件人是。

我现在所拥有的对2个用户之间的简单消息很有效。但是,一旦第三个用户回复同一个线程,它就无法正确显示。我目前的疑问是:

SELECT pm_info.is_read, sender.usrFirst as sender_name, pm_data.date_sent,  pm_data.title, pm_data.thread_id, pm_data.id as dataid, thread_max_date_sent
FROM pm_info
INNER JOIN pm_data ON pm_info.message_id = pm_data.id
INNER JOIN tblUsers AS sender ON pm_data.sender_id = sender.usrID
INNER JOIN (SELECT thread_id, sender_id, MAX(date_sent) AS thread_max_date_sent FROM pm_data GROUP BY thread_id, sender_id) deriv1 ON pm_data.thread_id = deriv1.thread_id AND pm_data.date_sent = deriv1.thread_max_date_sent AND pm_data.sender_id = deriv1.sender_id
WHERE pm_info.receiver_id = '$usrID'
ORDER BY deriv1.thread_max_date_sent DESC

假设$ usrID = 68(因此,receiver_id = 68),它输出:

From: Kyle (pm_data.id = 18) RE: single message (thread_id= 13587)
From: Ed (pm_data.id = 12)   RE: single message (thread_id= 13587)
From: Ed (pm_data.id = 8)    RE: Test Number 2 (thread_id= 16256)

注意thread_id(13587)如何显示两次,因为有2个不同的发件人。

我怎么能拥有只是显示最近的thread_id,无论发件人是谁?

非常感谢!!

4 个答案:

答案 0 :(得分:1)

尝试

SELECT pm_info.is_read, sender.usrFirst as sender_name, pm_data.date_sent,  pm_data.title, pm_data.thread_id, pm_data.id as dataid
FROM pm_data, pm_info, tblUsers as sender 
WHERE pm_info.message_id = pm_data.id 
  AND pm_data.sender_id = sender.usrID
  AND pm_info.receiver_id = '$usrID'
GROUP BY thread_id
ORDER BY date_sent DESC
LIMIT 0,1

答案 1 :(得分:0)

尝试

SELECT pm_info.is_read, group_concat(DISTINCT sender.usrFirst) as sender_name,
    pm_data.date_sent, pm_data.title, pm_data.thread_id, pm_data.id as dataid,
    MAX(date_sent) AS thread_max_date_sent
FROM pm_info
INNER JOIN pm_data ON pm_info.message_id = pm_data.id
INNER JOIN tblUsers AS sender ON pm_data.sender_id = sender.usrID
WHERE pm_info.receiver_id = '$usrID'
GROUP BY pm_data.thread_id
ORDER BY thread_max_date_sent DESC;

如果不满足您的需求,请随意不同意group_concat部分; 它只列出了所有相关的发件人,而不是任意选择一个。

答案 2 :(得分:0)

实际上,原始问题中的查询似乎只需要进行非常小的更改即可获得每个线程的实际最新记录。

  1. 将sender_id放入子查询的GROUP BY字段
  2. 在ON子句中删除 pm_data.sender_id = deriv1.sender_id
  3. SELECT pm_info.is_read, sender.usrFirst as sender_name, pm_data.date_sent,  pm_data.title, pm_data.thread_id, pm_data.id as dataid, thread_max_date_sent
    FROM pm_info
    INNER JOIN pm_data ON pm_info.message_id = pm_data.id
    INNER JOIN tblUsers AS sender ON pm_data.sender_id = sender.usrID
    INNER JOIN (SELECT thread_id, /*sender_id,*/ MAX(date_sent) AS thread_max_date_sent 
                    FROM pm_data GROUP BY thread_id /*, sender_id*/) deriv1 
        ON pm_data.thread_id = deriv1.thread_id AND pm_data.date_sent = deriv1.thread_max_date_sent /*AND pm_data.sender_id = deriv1.sender_id*/
    WHERE pm_info.receiver_id = '$usrID'
    ORDER BY deriv1.thread_max_date_sent DESC
    

    作为旁注:如果可能,在该子查询中查找max messageID而不是max(date_sent)

答案 3 :(得分:0)

我的建议是将数据库拆分为两个表以便更好地规范化:“thread”和“message”。有一些线程信息对所有消息都是通用的,比如线程标题。您通过重复相同的值在消息表中浪费空间。

您可以在线程表中添加“最后发布时间”字段,该表会在每个新帖子上更新。然后,从线程表中选择并按最后一篇文章排序只是一件简单的事情。它也会快得多。