Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Order SQL结果,其中引用同一表上另一条记录的每条记录位于被引用记录之后_Sql_Postgresql_Sql Order By - Fatal编程技术网

Order SQL结果,其中引用同一表上另一条记录的每条记录位于被引用记录之后

Order SQL结果,其中引用同一表上另一条记录的每条记录位于被引用记录之后,sql,postgresql,sql-order-by,Sql,Postgresql,Sql Order By,我有以下数据: id, parent_id 1, 3 2, null 3, 2 4, 2 其中,parent_id是对同一表的引用 我需要对这些列进行排序,以便每个记录都在其父记录之后(不一定紧跟其后) 因此,我预计会有这样的结果: id, parent_id 2, null 3, 2 1, 3 4, 2 我猜在没有任何重大模式更改的情况下,没有一种干净有效的方法可以做到这一点,但如果任何人都能想到一种方法,我会在这里提出这个问题 一种可能的方法是执行多个查询,其中每次父id都必须位于以前的

我有以下数据:

id, parent_id
1, 3
2, null
3, 2
4, 2
其中,parent_id是对同一表的引用

我需要对这些列进行排序,以便每个记录都在其父记录之后(不一定紧跟其后)

因此,我预计会有这样的结果:

id, parent_id
2, null
3, 2
1, 3
4, 2
我猜在没有任何重大模式更改的情况下,没有一种干净有效的方法可以做到这一点,但如果任何人都能想到一种方法,我会在这里提出这个问题


一种可能的方法是执行多个查询,其中每次父id都必须位于以前的查询结果之一中。但这样做效率不高。

您需要递归才能完成此任务:

with recursive hier as (
  select *, 0 as hlevel
    from idparent
   where parent_id is null
  union all
  select c.*, p.hlevel + 1
    from hier p
    join idparent c on p.id = c.parent_id
)
select * from hier
 order by hlevel;

 id | parent_id | hlevel 
----+-----------+--------
  2 |           |      0
  3 |         2 |      1
  4 |         2 |      1
  1 |         3 |      2
(4 rows)


您将需要递归来完成以下任务:

with recursive hier as (
  select *, 0 as hlevel
    from idparent
   where parent_id is null
  union all
  select c.*, p.hlevel + 1
    from hier p
    join idparent c on p.id = c.parent_id
)
select * from hier
 order by hlevel;

 id | parent_id | hlevel 
----+-----------+--------
  2 |           |      0
  3 |         2 |      1
  4 |         2 |      1
  1 |         3 |      2
(4 rows)


我认为最安全的方法是使用递归CTE来计算每个
id
的路径。然后只需排序:

with recursive cte as (
      select id, parent_id,  array[id] as path
      from t
      where parent_id is null
      union all
      select t.id, t.parent_id, path || array[t.id]
      from cte join
           t
           on cte.id = t.parent_id
     )
select *
from cte
order by path;

是一个dbfiddle。

我认为最安全的方法是使用递归CTE来计算每个
id
的路径。然后只需排序:

with recursive cte as (
      select id, parent_id,  array[id] as path
      from t
      where parent_id is null
      union all
      select t.id, t.parent_id, path || array[t.id]
      from cte join
           t
           on cte.id = t.parent_id
     )
select *
from cte
order by path;

是个傻瓜。

我很惊讶你竟然不接受这个答案。很抱歉,戈登,我同样喜欢这两个答案,但迈克先回答,所以我改了。如果你比Jon Skeet落后1分,我会把我的答案改回来:我很惊讶你竟然不接受这个答案。很抱歉,戈登,我同样喜欢这两个答案,但迈克先回答,所以我改了。如果你比Jon Skeet落后1分,我会改变我的回答:P