使用层次结构和用于排序的附加列对列进行排序
Sorting columns with hierarchy and additional column for sorting
我有以下结构:
id,
name,
parent_id,
order_by
和条目:
id | name | parent_id | order_by
----+-----------+-----------+----------
8 | Cat 1 | | 1
7 | Cat 2 | | 2
5 | Cat 3 | | 3
15 | Cat 1.1 | 8 | 1
17 | Cat 1.2 | 15 | 2
16 | Cat 2.1 | 8 | 1
20 | Cat 1.2.1 | 17 | 1
我想输出:
id | name | parent_id | order_by
----+-----------+-----------+----------
8 | Cat 1 | | 1
15 | Cat 1.1 | 8 | 1
17 | Cat 1.2 | 8 | 2
20 | Cat 1.2.1 | 17 | 1
7 | Cat 2 | | 2
16 | Cat 2.1 | 7 | 1
5 | Cat 3 | | 3
因此,使用 order_by
列对主要条目(没有 parent_id)进行排序,并使用 order_by
列对一个级别的子项进行排序。
注意:我假设 id
= 16 parent_id
应该是 7,而不是 8
您需要一个递归查询来遍历整个树。您需要一种方法来 "remember" 主排序顺序,然后按两个不同的标准排序:一个用于 "overall" 排序顺序,一个用于每个子级别:
with recursive tree as (
select id, name, parent_id, order_by as main_order, null::int as child_order
from category
where parent_id is null
union all
select c.id, c.name, c.parent_id, p.main_order, c.order_by as child_order
from category c
join tree p on p.id = c.parent_id
)
select *
from tree
order by main_order, child_order nulls first;
通过将 order_by
从根级别传递给所有子级,我们可以将属于同一根的所有行放在一起。然后根据假 child_order 对一个根的行进行排序 - 该列的根行将具有 null
,而 nulls first
将它们放在每组的开头。
我有以下结构:
id,
name,
parent_id,
order_by
和条目:
id | name | parent_id | order_by
----+-----------+-----------+----------
8 | Cat 1 | | 1
7 | Cat 2 | | 2
5 | Cat 3 | | 3
15 | Cat 1.1 | 8 | 1
17 | Cat 1.2 | 15 | 2
16 | Cat 2.1 | 8 | 1
20 | Cat 1.2.1 | 17 | 1
我想输出:
id | name | parent_id | order_by
----+-----------+-----------+----------
8 | Cat 1 | | 1
15 | Cat 1.1 | 8 | 1
17 | Cat 1.2 | 8 | 2
20 | Cat 1.2.1 | 17 | 1
7 | Cat 2 | | 2
16 | Cat 2.1 | 7 | 1
5 | Cat 3 | | 3
因此,使用 order_by
列对主要条目(没有 parent_id)进行排序,并使用 order_by
列对一个级别的子项进行排序。
注意:我假设 id
= 16 parent_id
应该是 7,而不是 8
您需要一个递归查询来遍历整个树。您需要一种方法来 "remember" 主排序顺序,然后按两个不同的标准排序:一个用于 "overall" 排序顺序,一个用于每个子级别:
with recursive tree as (
select id, name, parent_id, order_by as main_order, null::int as child_order
from category
where parent_id is null
union all
select c.id, c.name, c.parent_id, p.main_order, c.order_by as child_order
from category c
join tree p on p.id = c.parent_id
)
select *
from tree
order by main_order, child_order nulls first;
通过将 order_by
从根级别传递给所有子级,我们可以将属于同一根的所有行放在一起。然后根据假 child_order 对一个根的行进行排序 - 该列的根行将具有 null
,而 nulls first
将它们放在每组的开头。