问题描述
我有一个称为类别的实体,每个此类都可以具有任意数量的子类别。如果我知道类别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_by
和is_locked
。
is_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