2012-09-01 57 views
0

我想編寫一個論壇網站,我想顯示一個線程列表。每個線程應該伴隨有關於第一篇文章(線程的「頭部」)以及最後一篇文章的信息。我目前的數據庫結構如下:獲取線程中的第一個和最後一個職位

threads table: 
id - int, PK, not NULL, auto-increment 
name - varchar(255) 

posts table: 
id  - int, PK, not NULL, auto-increment 
thread_id - FK for threads 

該表還有其他字段,但它們與查詢無關。我有興趣查詢threads,並以某種方式JOINposts ing,這樣我就可以在單個查詢中獲得每個線程的第一個和最後一個帖子(沒有子查詢)。到目前爲止,我能夠使用多個查詢做到這一點,我已經定義了第一篇文章是幸福:

SELECT * 
FROM threads t 
LEFT JOIN posts p ON t.id = p.thread_id 
ORDER BY p.id 
LIMIT 0, 1 

最後的職位是非常除了ORDER BY id DESC相同。現在,我可以做選擇與他們的第一最新帖子多線程,:

SELECT * 
FROM threads t 
LEFT JOIN posts p ON t.id = p.thread_id 
ORDER BY p.id 
GROUP BY t.id 

但我當然不能在一次同時獲得,因爲我需要在這兩個ASCDESC排序同時。
這裏有什麼解決方案?甚至可以使用單個查詢嗎?有什麼辦法可以改變我的桌子的結構以促進這一點嗎?如果這不可行,那麼您可以給我什麼提示以改善這種特定情況下的查詢性能?

+2

您可以將這兩者聯合在一起,只要您將每個都放在'()'中,以便它的'ORDER BY'只適用於它自己。或者你可以加入一個子查詢,這將是高性能的。 –

+0

我需要爲_each_線程獲取第一個和最後一個帖子,所以我不認爲'UNION'會做到這一點。子查詢可能會。我會等待並看到其他建議。 – Grampa

回答

1

你可以做一些與子查詢和聯接:

SELECT first.text as first_post_text, last.text as last_post_text 
FROM 
    (SELECT MAX(id) as max_id, MIN(id) as min_id FROM posts WHERE thread_id = 1234) as sub 
JOIN posts first ON (sub.max_id = first.id) 
JOIN posts last ON (sub.min_id = last.id) 

但是,這並不解決這樣做沒有子查詢您的問題。

您可以向您的線程表添加列,以便保留每個線程的第一個和最後一個職位的ID。第一篇文章永遠不會改變,但是每次添加新文章時,您都必須在線索表中更新該記錄,這樣會使寫入次數翻倍,並且您可能需要使用事務來避免競爭狀況。

或者你可以去重複有關線程行中第一個和最後一個帖子的信息。假設您需要海報的user_id,發佈的時間戳和帖子的前100個字符。您可以在線程表中創建6個新列以包含第一篇和最後一篇文章的數據。它複製數據,但這意味着您可以顯示線程列表,而無需查詢帖子表。

+0

我很抱歉接受這個答案太久了。我決定與解決方案一起爲第一篇和最後一篇文章添加額外的列。儘管這意味着額外的寫入(和存儲空間),但性能增益足以證明它的合理性。謝謝! – Grampa

相關問題