2010-11-29 57 views
1

首先,对不起我的英语不好......MySQL中的高级JOIN查询?

我的一个MySQL查询出现问题。我有两个表:消息和答复。 消息表包含一个id,discussion_id,内容和日期字段。答复表包含一个ID,message_id,内容和日期字段。

我希望对于一个特定的讨论,最新的10条消息及其答复被提取。消息需要在最后一个回复中排序,回复需要首先排序。

(Facebook一样)

我是这样做的:

SELECT * FROM messages WHERE discussion_id = 'test' ORDER BY date DESC; 

,然后使用PHP foreach循环

SELECT * FROM replies WHERE message_id = 'test' ORDER BY date ASC; 

但是,如果我会用我所11个查询,这并不理想。我正在考虑加入或联合,但如果我这样做,答复和消息是不可分开的。该列表按照answers.date排序,但回复和他们的父母消息不再在一起。我正在使用:

SELECT * FROM messages LEFT JOIN replies ON messages.id = replies.message_id WHERE discussion_id='4cc43b40586b6' ORDER BY replies.date DESC 

是否可以为此任务进行一次查询?

+0

我这样做的时候,我总是在消息表中的列与最后回复日期(或者如果数据很简单,只是一个表的所有邮件和回复)。那么很容易先排序,然后再排序。仅供参考,它可能会为您在插入/更新期间优化这一点而不仅仅是获取时节省一些麻烦。 – 2010-11-29 15:31:25

回答

3

'IN'关键字怎么样?您可以将其总计减少到两个查询,因为您希望将回复与邮件分开。第一个查询是好的了,但对于第二个查询,(我没有检查这对数据库还,所以语法可能稍微偏离):

SELECT * 
FROM replies 
WHERE message_id IN (
    SELECT message_id 
    FROM messages 
    WHERE discussion_id = 'test' 
) 
ORDER BY date ASC; 

编辑(每建议在评论):

你也可以修改上面的连接以提高性能;它仍然给你两个查询共有的,但你想要的结果两套反正:

SELECT * 
FROM replies 
LEFT JOIN messages ON messages.id = replies.message_id 
WHERE discussion_id='4cc43b40586b6' 
ORDER BY replies.date ASC 
+1

哦,不,依赖子查询。将您的查询重写为加入 – cristian 2010-11-29 15:49:59

1

对于一个查询,你会想,你遍历这些结果得到的消息ID和响应ID,也对它们进行排序。否则,你需要更多的查询。

SELECT 
     messages.id AS messageid, 
     replies.id AS replyid, 
     *WHATEVER OTHER COLUMNS* 
FROM replies, messages 
WHERE replies.message_id = messages.discussion_id 
    AND messages.discussion_id = 'test' 
ORDER BY replies.date ASC; 

我不确定这是不是你正在寻找的东西,但是这可能会让你开始。