2009-08-08 61 views
4
id | message | reply id | date 

1  | my new app.. |  0   | 10/10/2009 (latest message on top, follow by replies) 
5  | love ur app.. |  1   | 11/10/2009 (this should show under the main message) 
6  | another comm |  1   | 12/10/2009 
2  | application 2 |  0   | 09/10/2009 
3  | reply of 2 |  2   | 11/10/2009 

我想顯示最新評論和主要評論後的答覆。很明顯,答覆將會有最新的日期,所以我不能按日期排序,因爲回覆將在主要日期之前。我不知道如何正確使用一個查詢來做到這一點。任何想法的請。複雜的SQL順序由

數據庫轉儲:http://pastie.org/576963

+0

示例如果困惑:http://pastie.org/577011 – Basit 2009-08-09 00:31:52

回答

6

我猜對於文章「reply id」爲0,並且是評論的文章編號。如果這是你的設計,這應該工作:

select * from yourTable 
order by 
    case when "reply id" = 0 then id else "reply id" end, id 

新增:感謝您對您的評論的附加信息。按照你想要的順序放置結果並不是那麼容易,因爲第一個排序鍵是線程啓動器帖子的created_date。這不在數據行中,所以你需要一個連接。這是基於附加信息我最好的猜測(這仍然是不夠完整的讓我從猜測):

select 
    f.id, f.user_id, f.type, f.reply_id, f.text, f.url, f.created_date, 
    coalesce(parentfeed.created_date,f.created_date) as thread_date 
from feed as f left outer join feed as parentfeed 
on f.reply_id = parentfeed.id 
order by 
    thread_date desc, 
    case when f.reply_id = 0 then 0 else 1 end, 
    created_date desc, id; 

您可能需要調整語法postgre。我在SQL Server中測試了這個。

如果這仍然沒有做到你想要的,請具體說明你希望如何恢復數據。最好告訴我,我應該看到您的轉儲文件中的數據的「id」順序,並且也是解釋了該順序的基礎。以下是我所做的:

  1. 應將線程(線程=消息及其註釋)中的所有消息組合在一起。

  2. 在一個線程中,將消息放在最上面,然後按照反向時間順序放置它的註釋。具有最近創建的/ _date的線程應該是第一個,然後是具有第二個最近的created_date的線程,依此類推。(你的樣本數據必須具有相同CREATED_DATE許多意見,所以我用「ID」作爲一個線程中的註釋輔助性的關鍵。)

注:轉儲表明CREATED_DATE是如果帖子被修改,則更新爲CURRENT_TIMESTAMP。如果這是一個實時留言板,請注意,這可能會導致註釋在父代消息之前被註明日期,並且這意味着如果頻繁修改(即使沒有對其文本進行實際更改),線程將保持在最前端。 (這與我的解決方案無關,但我認爲值得注意)。

因爲需要連接,所以此查詢現在會慢很多。我的建議:維護兩個日期列,「thread_last_modified」和「item_last_modified」。您將不得不將線程啓動器的更新級聯到註釋,但是如果沒有更新,我認爲這是值得的,因爲查詢可以更簡單。

select 
    id, user_id, type, reply_id, text, url, thread_last_modified, item_last_modified 
from feed 
order by 
    thread_last_modified desc, 
    case when f.reply_id = 0 then 0 else 1 end, 
    item_last_modified desc, id; 

添加了#2:因爲它需要一些改變你的設計,我沒有測試過這一點,如果你想只包含與標識的評論:: thisOne,我想你可以添加此行的主題ON和ORDER BY子句之間(我的第一個加入的解決方案,加入):

where parentfeed.id = (
    select coalesce(reply_id,id) 
    from feed 
    where id = ::thisOne 
) 

從理論上講,這個查詢應該只是一次查詢的評估,但如果它不是在實踐中,你可以預先計算它as :: thisOneThreadID並添加

where parentfeed.id = ::thisOneThreadID 

對於第二種方案,假設你又預先計算,嘗試

where coalesce(id,reply_id) = ::thisOneThreadID 

順便說一句,我懷疑我的兩個解決方案,將合併是最後一次在完全相同的時間修改線程...

+0

以及我希望最新的主要消息(reply_id = 0)在最上方,然後在每個回覆下正確消息應該去。 - 主要消息 - 回覆消息 - 主要消息 - 回覆消息 試試下面的SQL轉儲文件,看看你的查詢工作,不工作對我來說:http://pastie.org/578558 – Basit 2009-08-10 15:21:40

+0

也請看看日期,不要看id,id不會是整數,它會像youtube一樣有線id(id:CxewVEwed) – Basit 2009-08-10 15:27:38

+0

我仍然猜測你的數據意味着什麼。除非您提供您希望從數據中看到的結果,或者您想要查看結果的訂單的明確說明,否則轉儲沒有多大幫助。 從我的評論中可以看出,您需要加入。由於消息必須根據父消息的日期進行排序,因此表中的行沒有足夠的信息可供ORDER BY在沒有聯接的情況下解決問題。該id,而不是日期存儲在該行中。 我會添加到我原來的答案。 – 2009-08-10 22:29:35

2

.... order by(有些謂詞這是 「主要的意見」,而不是真正的followups)desc, date desc

既然你不說清楚有什麼區別一個「主要評論」,這就是我能爲你做的一切。如果,在你的榜樣,所有的主要意見有一個零reply_id,這可能是:

order by case reply_id = 0 then 1 else 0 end desc, date desc

注意,使用case語句,而不是僅僅通過reply_id排序是必要的,因爲你要第一個表達式對於所有非主消息具有相同的值(即零),以便它們僅由第二表達式date排序。

(哦,如果我理解你的模式,reply_id真的應該被命名爲in_repky_to_id

+0

這是一個我經常使用的有用技巧。 – 2009-08-09 01:54:51

+0

以及我想要最新的主要消息(reply_id = 0)在上面,然後在每個回覆消息的正下方去。 - 主要消息 - 回覆消息 - 主要消息 - 回覆消息 試試下面的SQL轉儲文件,看看你的查詢工作,不工作對我來說:http://pastie.org/578558 – Basit 2009-08-10 15:21:10

+0

也請看看日期,不要看id,id不會是整數,它會像youtube一樣有線id(id:CxewVEwed) – Basit 2009-08-10 15:28:09

0

我不知道你的要求,所以我的反應是一種抽象... 最大 - 可能需要是分鐘(同樣,我不是你的具體要求明確)

select 
    y.column1 
    , y.column2 
    , y.column3 
    , y.datecolumn 
from 
(select 
    column1 
    , max(datecolumn) as rank_date 
from tableA 
group by column1) as x 
inner join tableA y on x.id = y.id 
order by x.rank_date, y...., y.... desc, y... asc, etc... 

如果您正在使用SQL Server,有一個叫了過來ROW_NUMBER,你可以使用以及功能。

0

這是關於在關係數據庫中表示分層數據的鏈接。 http://dev.mysql.com/tech-resources/articles/hierarchical-data.html

要點是,你需要加入到你想去的層次深處。 提供的示例數據只有兩層。

SELECT 
f1.id AS `parent_id`, 
f1.text AS `parent_text`, 
f1.created_date AS `parent_created_date`, 
f2.* 
FROM 
feed AS `f1` 
LEFT JOIN feed `f2` ON (f1.id = f2.reply_id) 
WHERE f1.reply_id = 0 
ORDER BY f1.created_date DESC, f2.created_date DESC 
; 

父文章信息將在f1。*列中,子信息(回覆)將在f2。*列中。