PostgreSQL 递归 CTE - Return 如果找到错误值则为空
PostgreSQL Recursive CTE - Return Empty if false value found
使用递归查询,我正在使用 parent
id 字段查询字段的所有祖先。如果在任何祖先的 enabled
字段中找到 false
值,则查询应 return 空行。
假设我有以下 table 称为 my_table
Field
Type
id
integer
parent
integer
enabled
boolean
它填充了以下数据:
id
parent
enabled
1
null
true
2
1
true
3
1
true
4
2
true
我有以下递归查询:
WITH recursive my_rec AS
(
SELECT id, parent, enabled
FROM my_table
WHERE id = 4
UNION ALL
SELECT t.id, t.parent, t.enabled
FROM my_table t
INNER JOIN my_rec
ON t.id = my_rec.parent
)
SELECT *
FROM my_rec
对于 id = 4
这正确 returns
id
parent
enabled
4
2
true
2
1
true
1
null
true
但是假设我要更新 id
2
以便它从 enabled
true
更改为 false
。
示例:
id
parent
enabled
1
null
true
2
1
false
3
1
true
4
2
true
现在我希望我的查询 return 没有 id = 4
。这是因为在 id
4
的“祖先”树中,enabled
是 false
for id
2
.
如何更新上面的查询以实现此目的?
如果我没理解错你可以尝试使用NOT EXISTS
子查询来
judge cte if any enabled
is false 没有像你期望的那样显示任何东西,否则全部显示。
WITH recursive my_rec AS
(
SELECT id, parent, enabled
FROM my_table
WHERE id = 4
UNION ALL
SELECT t.id, t.parent, t.enabled
FROM my_table t
INNER JOIN my_rec
ON t.id = my_rec.parent
)
SELECT *
FROM my_rec
WHERE NOT EXISTS (
SELECT 1
FROM my_rec
WHERE enabled = false
)
或者我们可以用COUNT
条件聚合函数来做,得到false_cnt
和判断
WITH recursive my_rec AS
(
SELECT id, parent, enabled
FROM my_table
WHERE id = 4
UNION ALL
SELECT t.id, t.parent, t.enabled
FROM my_table t
INNER JOIN my_rec
ON t.id = my_rec.parent
)
SELECT *
FROM (
SELECT *,COUNT(*) FILTER(WHERE enabled = false) OVER() false_cnt
FROM my_rec
) t1
WHERE false_cnt = 0
使用递归查询,我正在使用 parent
id 字段查询字段的所有祖先。如果在任何祖先的 enabled
字段中找到 false
值,则查询应 return 空行。
假设我有以下 table 称为 my_table
Field | Type |
---|---|
id | integer |
parent | integer |
enabled | boolean |
它填充了以下数据:
id | parent | enabled |
---|---|---|
1 | null | true |
2 | 1 | true |
3 | 1 | true |
4 | 2 | true |
我有以下递归查询:
WITH recursive my_rec AS
(
SELECT id, parent, enabled
FROM my_table
WHERE id = 4
UNION ALL
SELECT t.id, t.parent, t.enabled
FROM my_table t
INNER JOIN my_rec
ON t.id = my_rec.parent
)
SELECT *
FROM my_rec
对于 id = 4
这正确 returns
id | parent | enabled |
---|---|---|
4 | 2 | true |
2 | 1 | true |
1 | null | true |
但是假设我要更新 id
2
以便它从 enabled
true
更改为 false
。
示例:
id | parent | enabled |
---|---|---|
1 | null | true |
2 | 1 | false |
3 | 1 | true |
4 | 2 | true |
现在我希望我的查询 return 没有 id = 4
。这是因为在 id
4
的“祖先”树中,enabled
是 false
for id
2
.
如何更新上面的查询以实现此目的?
如果我没理解错你可以尝试使用NOT EXISTS
子查询来
judge cte if any enabled
is false 没有像你期望的那样显示任何东西,否则全部显示。
WITH recursive my_rec AS
(
SELECT id, parent, enabled
FROM my_table
WHERE id = 4
UNION ALL
SELECT t.id, t.parent, t.enabled
FROM my_table t
INNER JOIN my_rec
ON t.id = my_rec.parent
)
SELECT *
FROM my_rec
WHERE NOT EXISTS (
SELECT 1
FROM my_rec
WHERE enabled = false
)
或者我们可以用COUNT
条件聚合函数来做,得到false_cnt
和判断
WITH recursive my_rec AS
(
SELECT id, parent, enabled
FROM my_table
WHERE id = 4
UNION ALL
SELECT t.id, t.parent, t.enabled
FROM my_table t
INNER JOIN my_rec
ON t.id = my_rec.parent
)
SELECT *
FROM (
SELECT *,COUNT(*) FILTER(WHERE enabled = false) OVER() false_cnt
FROM my_rec
) t1
WHERE false_cnt = 0