在具有附加条件的树中查找实体的后代PostgreSQL

问题描述

我有一个称为类别的实体,每个此类都可以具有任意数量的子类别。如果我知道类别ID,则可以通过以下方式跟踪其所有后代:

WITH RECURSIVE subcategories AS (
    select id,is_locked_by
    FROM category
    WHERE id = categoryId
    UNION
    SELECT c.id,c.is_locked_by
    FROM category c
    INNER JOIN subcategories subs on subs.id = c."parentCategoryId"
) 
SELECT id FROM subcategories;

每个类别都有两个参数:is_locked_byis_lockedis_locked_by参数指示锁定类别。例如,如果我有一个id为10的类别,其is_locked_by = 5,则意味着id为10的类别被id为5的类别锁定。从技术上讲,这意味着id为5的类别= 5用密码锁定,并且包含ID为10的类别。 is_locked参数表明类别已被锁定,这意味着密码直接在该类别上设置。

----19---
    |
    25
    |
26* | 27 | 28
|
29

这是类别树,应理解如下:类别19是顶级类别,它包含类别25,其中包含类别26、27和28,类别26包含第29个类别,id = 26的类别为锁定(用*表示)。

给出categoryId = 19,结果应为19、25、27和28。给定categoryId = 25,结果应为25、27和28。换句话说,我想查找所有is_locked = false的后代不受is_locked = true的那些类别的锁定。 如何编写这样的查询?

我希望我足够清楚......

解决方法

您想忽略锁定的类别及其子项。您只需在递归成员的WHERE子句中将它们过滤掉:

WITH RECURSIVE subcategories AS (
    select id,is_locked_by
    FROM category
    WHERE id = ?
    UNION ALL
    SELECT c.id,c.is_locked_by
    FROM category c
    INNER JOIN subcategories subs on subs.id = c."parentCategoryId"
    WHERE c.is_locked IS NULL
    ) 
SELECT id FROM subcategories;

根据is_locked列的数据类型和值,WHERE谓词可能有所不同。例如,如果是布尔值:

WHERE NOT c.is_locked

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...