【问题标题】:How to make ORDER SIBLINGS BY?如何订购兄弟姐妹?
【发布时间】:2013-07-19 02:39:12
【问题描述】:

我正在使用 PostgreSQL 9.1.6 并尝试构建递归 SQL。
我想在 SQL-Server 中像 ORDER SIBLINGS BY 那样排序。

编者注:这应该是指Oraclewhere ORDER SIBLINGS BY actually exists

测试表:

create table RECURSIVE_TEST(
  EMP_ID int,
  MANAGER_ID int,
  EMP_NAME varchar(30)
);

insert into recursive_test values
(1  ,0 ,'MANAGER1'),
(2  ,0 ,'MANAGER2'),
(3  ,0 ,'MANAGER3'),
(4  ,0 ,'MANAGER4'),
(5  ,1 ,'emp1'),
(6  ,3 ,'emp2'),
(7  ,4 ,'emp3'),
(8  ,2 ,'emp4'),
(9  ,2 ,'emp5'),
(10 ,3 ,'emp6'),
(11 ,4 ,'emp7'),
(12 ,3 ,'emp8'),
(13 ,4 ,'emp9'),
(14 ,2 ,'emp10'),
(15 ,2 ,'emp11'),
(16 ,1 ,'emp12');

查询:

WITH RECURSIVE T AS
(
    SELECT A.EMP_ID
             ,A.MANAGER_ID
             ,A.EMP_NAME
      FROM RECURSIVE_TEST A
    WHERE MANAGER_ID = 0
    UNION ALL
    SELECT A.EMP_ID
             ,A.MANAGER_ID
             ,A.EMP_NAME
      FROM RECURSIVE_TEST A, T
    WHERE A.MANAGER_ID = T.EMP_ID
)
SELECT * FROM T;

结果:

 emp_id | manager_id | emp_name 
--------+------------+----------
      1 |          0 | MANAGER1
      2 |          0 | MANAGER2
      3 |          0 | MANAGER3
      4 |          0 | MANAGER4
      5 |          1 | emp1
      6 |          3 | emp2
      7 |          4 | emp3
      8 |          2 | emp4
      9 |          2 | emp5
     10 |          3 | emp6
     11 |          4 | emp7
     12 |          3 | emp8
     13 |          4 | emp9
     14 |          2 | emp10
     15 |          2 | emp11
     16 |          1 | emp12

我想像下面这样对结果集进行排序。

 emp_id | manager_id | emp_name 
--------+------------+----------
      1 |          0 | MANAGER1
      5 |          1 | emp1
     16 |          1 | emp12      
      2 |          0 | MANAGER2
      8 |          2 | emp4
      9 |          2 | emp5
     14 |          2 | emp10
     15 |          2 | emp11      
      3 |          0 | MANAGER3
      6 |          3 | emp2
     10 |          3 | emp6
     12 |          3 | emp8     
      4 |          0 | MANAGER4
      7 |          4 | emp3
     11 |          4 | emp7
     13 |          4 | emp9

有什么建议吗?

【问题讨论】:

  • 也许你应该展示你拥有的语句、架构、PostgreSQL 版本,为那些不了解 Oracle 查询语言的人详细解释 ORDER SIBLINGS BY 等等。你已经得到了这个建议足够多,我不知道你为什么一直发布这么少的问题。
  • 现在,问题很好。其实很有趣。 +1
  • 同上。感谢您解决这个问题。顺便说一句,9.1.6 有一个令人讨厌的安全漏洞;见postgresql.org/support/security/faq/2013-04-04
  • @CraigRinger:由于您对 Q 的更新感到满意,您可能对new feature to retract a close vote 感兴趣。好吧,现在它已经关闭了,只剩下“重新打开”了。
  • @ErwinBrandstetter 是的,非常感兴趣。总是让我很恼火的是,closevote 对话是根据问题的当前状态来构建的,暗示它可能会有所改善,但是没有办法撤回 closevote 或投票反对 close。

标签: sql postgresql sql-order-by common-table-expression


【解决方案1】:

这将实现您所描述的:

对于一个层次结构

WITH RECURSIVE t AS (
   SELECT emp_id As top_id
        , emp_id
        , manager_id
        , emp_name
   FROM   recursive_test
   WHERE  manager_id = 0

   UNION ALL
   SELECT t.top_id
        , a.emp_id
        , a.manager_id
        , a.emp_name
   FROM   recursive_test a
   JOIN   t ON a.manager_id = t.emp_id
   )
SELECT emp_id
     , manager_id
     , emp_name
FROM   t
ORDER  BY top_id, emp_id;

您似乎想通过emp_idsecondary 订购..

对于任意数量的级别:

WITH RECURSIVE t AS (
   SELECT ARRAY[emp_id] AS hierarchy
        , emp_id
        , manager_id
        , emp_name
   FROM   recursive_test
   WHERE  manager_id = 0

   UNION ALL
   SELECT t.hierarchy || a.emp_id
        , a.emp_id
        , a.manager_id
        , a.emp_name
   FROM   recursive_test a
   JOIN   t ON a.manager_id = t.emp_id
   )
SELECT emp_id
     , manager_id
     , emp_name
FROM   t
ORDER  BY hierarchy;

这个将祖先(包括自身)收集在一个数组中并按它排序,实现类似于目录中的排序。

按数组排序按预期工作。相关:

【讨论】:

    猜你喜欢
    • 2019-05-06
    • 2019-08-29
    • 1970-01-01
    • 2014-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-06
    相关资源
    最近更新 更多