如何使用MySQL Join通过上次回复对论坛帖子进行排序?

时间:2013-06-19 14:02:41

标签: php mysql join

我为此编写查询时遇到了一些麻烦。我想我有基本的逻辑,虽然我可能没有。我想要做的是根据用户正在查看的主板获取所有线程,然后根据上次回复的时间对这些线程进行排序。查询不会返回任何错误,它只会获取最近更新的线程。

这是我的疑问:

$query = "
            SELECT
            t.child_id, t.thread_id,
            m.thread_id, m.message_id, m.date_posted
            FROM forum_threads AS t
            LEFT JOIN forum_messages AS m ON t.thread_id = m.thread_id
            WHERE t.child_id = ".$board_id."
            ORDER BY m.date_posted DESC
            LIMIT ".$starting.", ".$this->user['results_per_page'];

这是要返回的查询:

            SELECT t.child_id, t.thread_id, m.thread_id, m.message_id, m.date_posted   
            FROM forum_threads AS t   
            LEFT JOIN forum_messages AS m   
            ON t.thread_id = m.thread_id   
            WHERE t.child_id = 2   
            ORDER BY m.date_posted DESC LIMIT 0, 15 

enter image description here

enter image description here

更新

我试图接受ethrbunny建议的想法,虽然我完全迷失了导致它返回错误的原因。

$query = "
            SELECT
            t.board_id, t.thread_id
            FROM forum_threads AS t
            LEFT JOIN (
            SELECT m.thread_id, m.message_id
            FROM forum_messages AS m
            WHERE m.thread_id = t.thread_id
            ORDER BY m.message_id DESC
            LIMIT 1
            ) AS q
            WHERE t.board_id = ".$board_id."
            ORDER BY q.date_posted DESC
            LIMIT ".$starting.", ".$this->user['results_per_page'];
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE t.board_id = 4 ORDER BY q.date_posted DESC LIMIT' at line 11

7 个答案:

答案 0 :(得分:7)

SELECT ... , MAX(m.date_posted) AS latest_reply ...

GROUP BY t.thread_id
ORDER BY latest_reply DESC ...

但为什么date_posted是一个TEXT?不应该是日期时间,也可能是int(如果是时间戳)

因为永远无法在文本列上优化运行MAX,所以建议使用

MAX(m.message_id) AS latest_reply

相反,作为消息可能以日期顺序插入,应该是等效的。


编辑添加: 查询全部写完......

$query = "
SELECT t.thread_id, title, 
    MAX(m.message_id) AS latest_reply 
FROM forum_threads AS t
    LEFT JOIN forum_messages AS m ON t.thread_id = m.thread_id
WHERE t.child_id = ".$board_id."
GROUP BY t.thread_id
ORDER BY latest_reply DESC 
LIMIT ".$starting.", ".$this->user['results_per_page'];

答案 1 :(得分:2)

(SQLFiddle今天早上打架我 - 所以这主要是猜测)

select <columns> from forum_threads t0
  left join
  ( select <columns> from forum_messages m0 where m0.thread_id = t0.thread_id 
    order by m0.date_posted desc limit 1) as q0
  order by q0.date_posted desc;

我很好奇为什么你的日期字段是text。这将使得很难排序。

答案 2 :(得分:2)

Yo可以在ORDER BY中使用SELECT语句来选择线程回复的最新日期。可以在这里找到一个例子:

<强> SQL FIDDLE

使用你的表格会是这样的:

SELECT * FROM forum_threads ft ORDER BY (SELECT date_posted FROM forum_messages fm WHERE fm.thread_id = ft.thread_id ORDER BY date DESC LIMIT 1) DESC;

但请看一下提供的示例。首先按线程日期查询订单,然后按最新回复日期查询。

答案 3 :(得分:1)

我认为您的查询是正确的,请回显您的查询并检查LIMIT的值。

答案 4 :(得分:1)

简单地进行子选择以获取按线程ID分组的最新消息,然后将其连接到主表: -

$query = "SELECT t.board_id, t.thread_id, MaxMessageId
            FROM forum_threads AS t
            LEFT JOIN (SELECT thread_id, MAX(message_id) AS MaxMessageId FROM forum_messages GROUP BY m.thread_id ) AS q
            ON  q.thread_id = t.thread_id 
            WHERE t.board_id = ".$board_id."
            ORDER BY MaxMessageId DESC
            LIMIT ".$starting.", ".$this->user['results_per_page'];

答案 5 :(得分:1)

select UDID,CID,CType
from uploaded_design ud 
left join 
(select CID,CDesign,CType 
 from design_comment
 order by CID desc) dc 
on 
ud.UDID = dc.CDesign 
group by dc.CDesign
order by dc.CID

答案 6 :(得分:-1)

尝试以下查询

SELECT
    t.child_id, t.thread_id,
    m.thread_id, m.message_id, m.date_posted
FROM
  forum_threads AS t
  LEFT JOIN forum_messages AS m ON t.thread_id = m.thread_id
  LEFT JOIN forum_messages AS m1 ON m.thread_id = m1.thread_id AND m.date_posted < m1.date_posted
WHERE
  t.child_id = ".$board_id." AND m1.date_posted is null
ORDER BY m.date_posted DESC
LIMIT ".$starting.", ".$this->user['results_per_page'];