0
点赞
收藏
分享

微信扫一扫

Python 自动化运维:CI/CD与DevOps实践的深度探讨

律楷粑粑 2024-11-06 阅读 7

PostgreSQL 递归查询

WITH 提供了一种方式来书写在一个大型查询中使用的辅助语句。这些语句通常被称为公共表表达式或 CTE Common Table Expression,它们可以被看成是定义只在一个查询中存在的临时表。

可选的 RECURSIVE 修饰符将 WITH 从单纯的句法变成了一种在标准 SQL 中不能完成的特性。通过使用 RECURSIVE,一个 WITH 查询可以引用它自己的输出。

一个递归 WITH 查询的通常形式总是一个非递归项,然后是 UNION 或者 UNION ALL,再然后是一个递归项,其中只有递归项能够包含对于查询自身输出的引用。

在使用递归查询时,确保查询的递归部分最终将不返回元组非常重要,否则查询将会无限循环。在某些时候,使用 UNION 替代 UNION ALL 可以通过抛弃与之前输出行重复的行来达到这个目的。

下面是我构造的一个关于递归查询的案例。


说明:有一个树状层次结构的表 tree_test,里面存储了整个树状结构的关系层次。现在有这样的需求,就是我知道某个层次结构,现在想查询出他的子节点,或者是其上层的所有节点的相关信息。
备注:假设 1 2 3 节点位于第一层,4 5 6 是节点 1 的子节点,7 8 9 10 是节点 2 的子节点,11 12 13 14 是节点 3 的子节点。

CREATE TABLE tree_test (
id INT,
cname VARCHAR(40),
parentid INT,
tstate INT,
PRIMARY KEY(id));
CREATE INDEX IF NOT EXISTS ix_tree_test_parentid ON public.tree_test USING btree(parentid);

INSERT INTO tree_test VALUES(1,'a',0,1);
INSERT INTO tree_test VALUES(2,'b',0,1);
INSERT INTO tree_test VALUES(3,'c',0,1);

INSERT INTO tree_test VALUES(4,'aa',1,1);
INSERT INTO tree_test VALUES(5,'aaa',1,1);
INSERT INTO tree_test VALUES(6,'aaaa',1,1);
INSERT INTO tree_test VALUES(7,'bb',2,1);
INSERT INTO tree_test VALUES(8,'bbb',2,1);
INSERT INTO tree_test VALUES(9,'bbbb',2,1);
INSERT INTO tree_test VALUES(10,'bbbbb',2,1);

INSERT INTO tree_test VALUES(11,'cc',3,1);
INSERT INTO tree_test VALUES(12,'ccc',3,1);
INSERT INTO tree_test VALUES(13,'cccc',3,1);
INSERT INTO tree_test VALUES(14,'ccccc',3,1);

SELECT * FROM tree_test;

说明:现在有个需求,就是我想知道节点 1 和他所有的子节点的信息。就可以使用如下的方法实现。
递归查询,从上向下
WITH RECURSIVE tree AS (
SELECT *
FROM tree_test
WHERE id = 1 AND parentid = '0'
UNION ALL
SELECT tree_test.*
FROM tree_test,
     tree
WHERE tree_test.parentid = tree.id )

SELECT *
FROM tree;

说明:现在有个需求就是我想知道节点 14 和他所有的父节点的信息。可以使用如下的方法进行实现。
递归查询从下向上
WITH RECURSIVE tree AS (
SELECT *
FROM tree_test
WHERE id = 14
UNION ALL
SELECT tree_test.*
FROM tree_test,
     tree
WHERE tree_test.id = tree.parentid )

SELECT *
FROM tree;

由于我这里只是做 demo 性的测试,有的看起来不是那么直观。如果的树状结构层次在 4-5 层的时候这种就非常直观。

举报

相关推荐

0 条评论