1

我正在处理数据库中的 postgres,我们在下表中列出了用于存储层次结构 ID的PATH列。ltree

表(位置)-

| ID(PK) |   User   |PATH (parent hierarchy) |
|--------|----------|---------|
|    1   |  Parent  |   null  |
|    2   |  Child-1 |   1     |
|    3   |  Child-2 |   1.2   |
|    4   |  Child-3 |   1.2.3 |
|    5   |  AParent |   null  |
|    6   |  AChild-2|   5     |
|    7   |  AChild-3|   5.6   |
|    8   |  AChild-4|   5.6   |

尝试以下查询 -

select loc.user,STRING_TO_ARRAY(concat(loc.PATH::text,'.',loc.id),'.') as path
from location loc
WHERE LOC.NAME ilike '%child%';

结果 -

|   ID   |   User   |   PATH  |
|--------|----------|---------|
|    2   |  Child-1 |{1,2}    |
|    3   |  Child-2 |{1,2,3}  |
|    4   |  Child-3 |{1,2,3,4}|
|    6   |  AChild-2|{5,6}    |
|    7   |  AChild-3|{5,6,7}  |
|    8   |  AChild-4|{5,6,8}  |

在这里你可以看到我们在表中有多个层次结构,但我想要唯一的层次结构直到叶子,例如

Hierarchy -1
A>B>C
Hierarchy -2
A>B>C>D`

预期结果应该是 -

   A>B>C>D

因为 A>B>C 也属于同一个保护伞。所以最终表的预期结果——

|   ID   |   User   |   PATH   |
|--------|----------|----------|
|    4   |  Child-3 |{1,2,3,4} |
|    7   |  AChild-3|{5,6,7}   |
|    8   |  Child-4 |{5,6,8}   |

管理父子关系的表与显示用户层次结构的路径相同。

如果还有其他需要,请告诉我。

4

1 回答 1

3

你可以通过检查一个节点是否有任何后代来找到叶子:

select *
from location l1
where l1.path is not null
and not exists (
    select from location l2
    where l2.path <@ l1.path 
    and l2.path <> l1.path
    )
order by l1.id

在db<>fiddle中测试它。

查询比它可能的更复杂,因为您的使用ltree有点不合逻辑。Roots 不应该是null,所有层次结构信息都应该包含在ltree列中,而您不必将其与id.

于 2022-02-28T12:17:50.727 回答