2011-06-29 93 views
2

我有兩個表Post (id, ..., creationdate)Post_Has_Post(parent_id, child_id)SQL:通過(可選)關係訂購結果

某些職位可以是父母的一部分< - >子女關係,並在​​表中具有相應的條目 - 表。

我想要做的是獲取由其creationdate排序的帖子列表。但是,其他職位的任何子女都應該在其父母之後插入結果。 現在當然很容易通過creationdate訂購,但是我對第二種分揀條件沒有想法。有沒有辦法做到這一點?

Post        Post_Has_Post 
+------+-------+--------------+ +-----------+----------+ 
| id | ... | creationdate | | parent_id | child_id | 
+------+-------+--------------+ +-----------+----------+ 
| 1 | ... | 2010-11-01 | | 1  | 3  | 
| 2 | ... | 2010-11-02 | +-----------+----------+ 
| 3 | ... | 2010-11-03 | 
+------+-------+--------------+ 

我需要整理這樣的結果:

Post 
+------+-------+--------------+ 
| id | ... | creationdate | 
+------+-------+--------------+ 
| 1 | ... | 2010-11-01 | 
| 3 | ... | 2010-11-03 | 
| 2 | ... | 2010-11-02 | 
+------+-------+--------------+ 

是否有通過排序來解決此問題的方法?

+0

您是否允許多層次的父子關係? I.e .: 1是3的父親,3是2的父母。這將改變的事情,以及... –

+0

另外,你的設計允許一個職位有兩個父母。那麼你的輸出將如何? –

+0

@阿德里安你是對的,我會擺脫關係表 –

回答

4

假設父母總是在孩子面前,這應該工作。

SELECT p.id, ..., creationdate 
    FROM Post p 
     LEFT JOIN Post_Has_Post php 
      ON p.id = php.child_id 
    ORDER BY COALESCE(php.parent_id, p.id), 
      creationdate 
+0

我期待在'ORDER BY'這個'CASE',但如果它適用於OP我會把它:) – JNK

+0

這工作, 非常感謝!直到現在我還沒有意識到這個功能! –

2

您不應該有表Post_Has_Parent。相反,請查看 將列添加到「parent_id」的Post表中,並使用post_id和parent_id之間的關係以及自加入。當 某人發佈帖子的回覆時,只需將其父帖子ID作爲新帖子的parent_id 即可。這將允許您將 關係存儲在一個表中。

根據的DBMS,你可以考慮使用:

甲骨文:Connect_be

select seq_num, post_text, parent_id, SYS_CONNECT_BY_PATH(seq_num, 
'/') AS PATH, level 
 from post 
start with seq_num = 1 
CONNECT BY NOCYCLE PRIOR seq_num = parent_id; 

的SQL Server:通用表表達式

;with posts as 
(

      select seq_num, post_text, parent_id, 0 AS generation, 
              CAST(seq_num as varchar(50)) as path 
              from recurs_test 
              where parent_id is NULL 
      UNION ALL 
      select e.seq_num, e.post_text, e.parent_id, generation + 1, 
              CAST(rtrim(p.path) + '/' +  CAST(e.seq_num as varchar(5)) as 
varchar(50)) as path 
              from recurs_test e 
              inner join posts p 
              on e.parent_id = p.seq_num 

) 

select seq_num, name, parent_id, dir, generation from 
managers order by dir; 

MYSQL:你將不得不看使用某種樹 遍歷算法並進行深度優先搜索。它們都非常複雜,通常涉及在數據庫中存儲某些內容(路徑,左側值和右側值等)。原因是MYSQL不允許 允許任何遞歸選擇語句(糾正我,如果我錯了,所以我 可以重做我已經寫了一些代碼!!)

+0

儘管如此,它並不回答這個問題。它應該是一個評論,而不是一個答案。 –

+2

雖然這並沒有解決排序的問題。也許發表一個建議,告訴你如何按照你提出的結構以所需的順序顯示。 – JNK

+0

@adrian - 他/她的代表太低評論我認爲。 – JNK

1

你不會在一個列中的日期,但恕我直言,這是有點混亂無論如何。您可以選擇在任何用戶界面呈現數據時顯示子線程日期或父線程日期:

SELECT Parent.ID, Parent.CreationDate ParentCreationDate, 
     Child.CreationDate ChildCreationDate 
FROM Post Parent LEFT OUTER JOIN 
    Post_Has_Post PHP ON Parent.ID = PHP.Parent_ID LEFT OUTER JOIN 
    Post Child ON PHP.Child_ID = Child.ID 
ORDER BY Parent.CreationDate, Child.CreationDate; 
+2

您可以使用'COALESCE(Parent.CreationDate,Child.Creationdate)AS CreationDate'將其顯示在單個字段中。 – JNK

+0

@JNK:好點。實際上,我的查詢應該也可以爲父/子帖子ID做這件事。 – Yuck