postgresql with 子句——迹忆客-ag捕鱼王app官网
在 postgresql 中,with 子句提供了一种编写辅助语句的方法,以便在更大的查询中使用。
with 子句有助于将复杂的大型查询分解为更简单的表单,便于阅读。这些语句通常称为通用表表达式(common table express, cte),也可以当做一个为查询而存在的临时表。
with 子句是在多次执行子查询时特别有用,允许我们在查询中通过它的名称(可能是多次)引用它。
with 子句在使用前必须先定义。
语法
with 查询的基础语法如下:
with
name_for_summary_data as (
select statement)
select columns
from name_for_summary_data
where conditions <=> (
select column
from name_for_summary_data)
[order by columns]
name_for_summary_data 是 with 子句的名称,name_for_summary_data 可以与现有的表名相同,并且具有优先级。
可以在 with 中使用数据 insert, update 或 delete 语句,允许您在同一个查询中执行多个不同的操作。
with 递归
在 with 子句中可以使用自身输出的数据。
公用表表达式 (cte) 具有一个重要的优点,那就是能够引用其自身,从而创建递归 cte。递归 cte 是一个重复执行初始 cte 以返回数据子集直到获取完整结果集的公用表表达式。
示例
创建 company 表( ),数据内容如下:
jiyik_db=# select * from company;
id | name | age | address | salary
---- ------- ----- ----------- --------
1 | paul | 32 | california| 20000
2 | allen | 25 | texas | 15000
3 | teddy | 23 | norway | 20000
4 | mark | 25 | rich-mond | 65000
5 | david | 27 | texas | 85000
6 | kim | 22 | south-hall| 45000
7 | james | 24 | houston | 10000
(7 rows)
下面将使用 with 子句在上表中查询数据:
with cte as
(select
id
, name
, age
, address
, salary
from company )
select * from cte;
结果如下:
id | name | age | address | salary
---- ------- ----- ----------- --------
1 | paul | 32 | california| 20000
2 | allen | 25 | texas | 15000
3 | teddy | 23 | norway | 20000
4 | mark | 25 | rich-mond | 65000
5 | david | 27 | texas | 85000
6 | kim | 22 | south-hall| 45000
7 | james | 24 | houston | 10000
(7 rows)
接下来让我们使用 recursive 关键字和 with 子句编写一个查询,查找 salary(工资) 字段小于 20000 的数据并计算它们的和:
with recursive t(n) as (
values (0)
union all
select salary from company where salary < 20000
)
select sum(n) from t;
结果如下:
sum
-------
25000
(1 row)
下面我们建立一张和 company 表相似的 company1 表,使用 delete 语句和 with 子句删除 company 表中 salary(工资) 字段大于等于 30000 的数据,并将删除的数据插入 company1 表,实现将 company 表数据转移到 company1 表中:
create table company1(
id int primary key not null,
name text not null,
age int not null,
address char(50),
salary real
);
with moved_rows as (
delete from company
where
salary >= 30000
returning *
)
insert into company1 (select * from moved_rows);
结果如下:
insert 0 3
此时,campany 表和 campany1 表的数据如下:
jiyik_db=# select * from company;
id | name | age | address | salary
---- ------- ----- ------------ --------
1 | paul | 32 | california | 20000
2 | allen | 25 | texas | 15000
3 | teddy | 23 | norway | 20000
7 | james | 24 | houston | 10000
(4 rows)
jiyik_db=# select * from company1;
id | name | age | address | salary
---- ------- ----- ------------- --------
4 | mark | 25 | rich-mond | 65000
5 | david | 27 | texas | 85000
6 | kim | 22 | south-hall | 45000
(3 rows)