2013-06-30 160 views
0

如何排序的數據我存儲線程與父/子關係的論壇如下:與父/子關係

CREATE TABLE forum_threads (
    thread_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, 
    parent_id INTEGER UNSIGNED NOT NULL DEFAULT 0, 
    topic_id INTEGER UNSIGNED NOT NULL, 
    user_id INTEGER UNSIGNED NOT NULL, 
    title VARCHAR(100) NOT NULL, 
    body TEXT NOT NULL, 
    create_date DATETIME NOT NULL, 

    PRIMARY KEY (thread_id), 
    FOREIGN KEY (parent_id) 
    REFERENCES forum_threads(thread_id), 
    FOREIGN KEY (topic_id) 
    REFERENCES forum_topics(topic_id), 
    FOREIGN KEY (user_id) 
    REFERENCES users(user_id) 
); 

新線程具有parent_id = 0,而回復有parent_id = the thread being replied to。現在我很困惑的是,我想顯示最近回覆排序的線程列表:

SELECT * FROM forum_threads 
WHERE topic_id = :topic_id AND parent_id = 0 
ORDER BY ??? DESC LIMIT :start, :display 

不確定如何完成此操作?

+0

外界問題對我來說:':'是什麼意思? (前':topic_id'或':start'? –

+0

@PRPGFerret我正在使用一個PDO包裝器,':'是一個佔位符,用於準備語句。 –

回答

2

如果我正確理解結構,那麼這些答覆就是指那些指向thread_id「父」線程的parent_id的那些行。

如果是這種情況,像這樣的自加入將起作用 - 請注意SELECT *必須去,因爲(a)您從兩個表中選擇,所以*意味着「兩個表中的所有行」和(b ),你需要GROUP BY具體列:

SELECT 
    parent.thread_id, 
    parent.parent_id, 
    parent.topic_id, 
    parent.user_id, 
    parent.title, 
    parent.body, 
    parent.create_date, 
    MAX(reply.create_date) AS reply_date 
FROM forum_threads parent 
INNER JOIN forum_threads reply ON parent.thread_id = reply.parent_id 
WHERE topic_id = whatever AND parent_id = 0 
GROUP BY 
    parent.thread_id, 
    parent.parent_id, 
    parent.topic_id, 
    parent.user_id, 
    parent.title, 
    parent.body, 
    parent.create_date 
ORDER BY reply_date DESC 
+0

嗨,Ed幾乎完美,唯一的問題是當沒有孩子(回覆)時,我希望它默認爲parent.create_date。當線程沒有孩子時,它似乎返回一個空的結果集。 –

3

如果父母不能有父母,你可以使用這樣的查詢:

SELECT * 
FROM forum_threads 
ORDER BY 
    CASE WHEN parent_id=0 THEN thread_id ELSE parent_id END DESC, 
    Parent_id!=0, 
    thread_id DESC 

這將列出所有線程降序排列,與最近的一個有序的答覆。

+0

對我來說很完美! –

1

像這樣的事情也將工作:

SELECT * FROM forum_threads `t1` 
WHERE topic_id = :topic_id AND parent_id = 0 
ORDER BY (SELECT `create_date` FROM `forum_threads` WHERE `parent_id`=`t1`.`thread_id` ORDER BY `create_date` DESC LIMIT 1) DESC LIMIT :start, :display 

埃德吉布斯的解決方案是更好,如果你需要訪問的答覆日期(我需要另一個子查詢)但如果​​你不需要d it,這是一個更簡單的解決方案(恕我直言)。