SQL:按(可选)关系排序结果

时间:2011-06-29 15:10:16

标签: sql sql-order-by relation

我有两张表Post (id, ..., creationdate)Post_Has_Post(parent_id, child_id)

某些帖子可以是父级< - >子关系的一部分,并且在Post_Has_Post - 表格中有相应的条目。

我要做的是获取由他们的创建日期订购的帖子列表。但是,其他职位的任何子女都应该在父母的结果中插入。 现在当然可以通过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   |
+------+-------+--------------+

有没有办法通过排序来解决这个问题?

3 个答案:

答案 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

答案 1 :(得分:2)

你不应该有表Post_Has_Parent。而是考虑一下 将列添加到“parent_id”的Post表并使用 post_id和parent_id之间的关系以及自联接。什么时候 有人发帖回复帖子,只是把父母的帖子ID作为 新帖子的parent_id。这将允许您存储 在一张桌子上的关系。

您可以使用以下方式查看DBMS:

Oracle: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没有 允许任何递归选择语句(如果我错了,请纠正我,所以我 可以重做我写的一些代码!! )

答案 2 :(得分:1)

你不会在一列中有日期,但恕我直言,这有点令人困惑。您可以选择在呈现数据的任何UI中显示子线程日期或父线程日期:

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;