sql – Trees:计算2条路径的成本并确定哪条路径更贵

这是我在这个论坛上的第一个问题,所以我会尽量保持清醒.

我有1个表实体,包含以下数据:

ATTR1                ATTR2                 ATTR3                 ATTR4

A                    Level 1                null                   35
B                    Level 2                 A                     34
C                    Level 2                 A                     33
D                    Level 3                 B                     32
E                    Level 3                 B                     31
F                    Level 3                 C                     30
G                    Level 3                 C                     29
H                    Level 4                 D                     28
I                    Level 4                 D                     27
J                    Level 4                 E                     26
K                    Level 4                 E                     25
L                    Level 4                 F                     24
M                    Level 4                 F                     23
N                    Level 4                 G                     22
O                    Level 4                 G                     21
P                    Level 5                 H                     20
Q                    Level 5                 H                     19
R                    Level 5                 H                     18
S                    Level 5                 O                     17

其中ATTR1是节点的名称.它也是主要关键.
其中ATTR2是节点的级别.
其中ATTR3是节点父节点的名称. A是根,它没有父节点,因此为NULL.
其中ATTR4是节点的成本.

现在的问题是:

>给定任何部分X和叶节点Y(即Y是X的后代),从根到X或从X到Y的直接后代最昂贵的路径是什么?

换句话说,假设X节点是D而Y节点是P.从节点到根的路径是D-B-A,而从叶到节点的路径是P-H-D.

如何计算每条路径的总成本并且能够说哪个更昂贵?

我的方法是做2个递归查询,每个路径1个查询以找到每个的SUM.问题是我被迫创建了2个表,并尝试将所有数据都放在1​​中.我觉得我已经走到了尽头,它看起来有点长,不可行.

感谢任何帮助,最好是PostgreSQL语法.

最佳答案 创建这样的表:

create table entity (attr1 text not null primary key,
                     attr2 text not null,
                     attr3 text,
                     attr4 int not null);

…并用上面显示的数据填充它,你在找这样的东西吗?:

with recursive cst as (
with req as (
select 'A'::text as top, 'D'::text as bottom
union all
select 'D'::text, 'P'::text
)
select
    top,
    bottom,
    top as last,
    top as path,
    attr4 as cost
  from req
  join entity on (top = attr1)
union
select
    top,
    bottom,
    attr1,
    path || '-' || attr1,
    cost + attr4
  from cst
  join entity on (attr3 = last)
), res as (
select * from cst where bottom = last
)
select path from res
   where cost = (select max(cost) from res);

当然,req CTE作为一种指定请求的方式是一种破解,但我相信你可以按照你想要的那样完成那部分.此外,这总是显示从“上部”到“下部”而不是“外部”到“内部”的路径,但我不确定这对您来说是否重要.无论如何,我认为这应该足够接近你想要的东西.

点赞