我需要按列从表中订购记录。客户使用的旧系统是手动选择的level 1
项,然后是level 2
的1级项目的所有子项,然后依次为level 5
。这是可怕的恕我直言,因为它需要数百个查询和调用数据库。
所以在新的数据库结构中,如果可能的话,我试图让它向数据库进行一次查询,并让它第一次正确排序。客户希望以这种方式向他们展示,所以我别无选择,只能想办法以这种方式订购。
这是项目及其等级代码的示例(1为单位数代码,2为2位数代码,3为4位数代码,4为6位数代码,5级为8位数代码):
基本上应该命令以5开头的所有内容都在代码5下面。以51开头的所有东西都在代码51下。如果你看一下n_mad_id
列它会链接到“母亲”ID代码是该代码的母亲,因此代码51的母亲是代码5.代码5101的母亲是代码51.代码5201的母亲是代码52.依此类推。
然后n_nivel
列是代码所属的级别。每个代码都有一个级别和一个母亲。顶级代码(即1,2,3,4,5)都是1级,因为它们只有一位数。
我希望有一种简单的ORDER BY
方法可以做到这一点。我已经玩了两天了,似乎无法服从它。
答案 0 :(得分:1)
绝对最简单的方法是将n_cod
字段转换为text
,然后按顺序排序:
SELECT *
FROM mytable
WHERE left(n_cod::text, 1) = '5' -- optional
ORDER BY n_cod::text;
不漂亮,但功能齐全。
您可以考虑更改表定义以使n_cod
类型为char(8)
,因为您无论如何都不会将其用作数字(在执行计算的意义上)。这会使查询更快。
答案 1 :(得分:0)
有趣的任务。据我所知,你想得到像
那样的结果n_id n_cod n_nivel n_mad_id
10 5 1 0
11 51 2 10
12 5101 3 11
14 510101 4 12
...
13 52 2 10
...
如果是,那么它可以做到这一点:
with recursive
tt(n_id, n_mad_id, n_cod, x) as (
select t.n_id, t.n_mad_id, t.n_cod, array[t.n_id]
from yourtable t where t.n_mad_id = 0
union all
select t.n_id, t.n_mad_id, t.n_cod, x || t.n_id
from tt join yourtable t on t.n_mad_id = tt.n_id)
select * from tt order by x;
这是我原来的测试查询:
create table t(id, parent) as values
(1, null),
(3, 1),
(7, 3),
(5, 3),
(6, 5),
(2, null),
(8, 2),
(4, 2);
with recursive
tt(id, parent, x) as (
select t.id, t.parent, array[t.id] from t where t.parent is null
union all
select t.id, t.parent, x || t.id from tt join t on t.parent = tt.id)
select * from tt order by x;
及其结果:
id | parent | x
----+--------+-----------
1 | (null) | {1}
3 | 1 | {1,3}
5 | 3 | {1,3,5}
6 | 5 | {1,3,5,6}
7 | 3 | {1,3,7}
2 | (null) | {2}
4 | 2 | {2,4}
8 | 2 | {2,8}
(8 rows)