赞
踩
WITH提供了一种编写辅助语句的方法,以便在较大的查询中使用。这些语句通常被称为公共表表达式或CTE,可以认为它们定义了仅为一个查询而存在的临时表。WITH子句中的每个辅助语句可以是SELECT、INSERT、UPDATE或DELETE;WITH子句本身附加到主语句,主语句也可以是SELECT、INSERT、UPDATE或DELETE。
先通过一个简单的CTE示例了解WITH查询,如下所示:
- WITH t as
- (SELECT generate_series(1,3))
- SELECT * FROM t;
结果:
这个简单的CTE示例中,一开始定义了一条辅助语句t取数,之后在主查询语句中查询t,定义的辅助语句就像是定义了一张临时表,对于复杂查询如果不使用CTE,可以通过创建视图方式简化SQL。
可选的 RECURSIVE修饰符从单纯的语法便利变成了一个功能,可以完成标准SQL中不可能完成的任务。使用RECURSIVE,WITH查询可以引用它自己的输出。从而实现递归,一般用于层次结构或树状结构的应用场景。注:严格地说,这个过程是迭代而不是递归,但是递归是SQL标准委员会选择的术语。
例如,创建表准备数据:
- create table area(id int,name text,fatherid int);
-
- insert into area values(1, '中国', 0),(2, '北京', 1),(3, '上海', 1),(4, '昌平区', 2),(5, '黄浦区', 3);
使用PostgreSQL的WITH查询检索ID为 5 以及以上的所有父节点:
- WITH RECURSIVE r AS
- (SELECT *
- FROM area
- WHERE id = 5
- UNION ALL
- SELECT area.*
- FROM area,
- r WHERE area.id = r.fatherid )
- SELECT *
- FROM r
- ORDER BY id;
结果:
使用PostgreSQL的WITH查询检索ID为 4 以及以上的所有父节点:
- WITH RECURSIVE r AS
- (SELECT *
- FROM area
- WHERE id = 4
- UNION ALL
- SELECT area.*
- FROM area,
- r WHERE area.id = r.fatherid )
- SELECT *
- FROM r
- ORDER BY id;
结果:
在处理递归查询时,务必确保查询的递归部分最终不会返回元组,否则查询将无限循环。有时候,使用UNION代替UNION ALL可以通过丢弃前面重复输出的行来实现这一点。然而,循环通常不涉及完全重复的输出行:可能需要只检查一个或几个字段,以查看以前是否达到了相同的点。处理这种情况的标准方法是计算已访问值的数组。递归查询求值算法以广度优先的搜索顺序产生输出。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。