在PostgreSQL中,WITH子句提供了一种编写辅助语句的方法,刹车在更大的查询中使用。
这些语句通常称为通用表表达式(Common Table Express,CTE),也可以当做一个为查询而存在的临时表。
WITH子句是在多次执行子查询时特别有用,允许我们在查询中通过它的名称(可能是多次)引用它。
WITH子句在使用前必须先定义。
语法
与查询的基础语法如下:
与 name_for_summary_data AS( SELECT语句) SELECT列 来自name_for_summary_data 条件<=>( SELECT栏 来自name_for_summary_data) [ORDER BY栏]
name_for_summary_data是WITH子句的名称,name_for_summary_data可以与现有的表名相同,并且具有优先级。
可以在WITH中使用数据INSERT,UPDATE或DELETE语句,允许您在同一个查询中执行多个不同的操作。
与递归
在WITH子句中可以使用自身输出的数据。
公用表表达式(CTE)具有一个重要的优点,那就是能够引用其自身,从而创建递归CTE。递归CTE是一个重复执行初始CTE以返回数据子集直到获取完整结果集的公用表表达式。
实例
创建COMPANY表(下载COMPANY SQL文件),数据内容如下:
runoobdb#select * from COMPANY; id | 名称| 年龄| 地址| 薪水 ---- + ------- + ----- + ----------- + -------- 1 | 保罗| 32 | 加利福尼亚| 20000 2 | 艾伦| 25 | 德州| 15000 3 | 泰迪 23 | 挪威| 20000 4 | 马克| 25 | 富蒙德| 65000 5 | 大卫| 27 | 德州| 85000 6 | 金| 22 | 南厅| 45000 7 | 詹姆斯| 24 | 休斯顿| 10000 (7列)
下面将使用WITH子句在上表中查询数据:
与CTE AS (选择 ID , 名称 年龄 , 地址 ,薪水 来自公司) 选择*从CTE;
得到结果如下:
id | 名称| 年龄| 地址| 薪水 ---- + ------- + ----- + ----------- + -------- 1 | 保罗| 32 | 加利福尼亚| 20000 2 | 艾伦| 25 | 德州| 15000 3 | 泰迪 23 | 挪威| 20000 4 | 马克| 25 | 富蒙德| 65000 5 | 大卫| 27 | 德州| 85000 6 | 金| 22 | 南厅| 45000 7 | 詹姆斯| 24 | 休斯顿| 10000 (7列)
接下来让我们使用RECURSIVE关键字和WITH子句编写一个查询,查找SALARY(工资)细分小于20000的数据并计算它们的和:
递归t(n)AS( 值() 全联盟 从工资<20000的公司中选择工资 ) 从t中选择sum(n);
得到结果如下:
和 ------- 25000 (1列)
下面我们建立一张表和COMPANY表相似的COMPANY1表,使用DELETE语句和WITH子句删除COMPANY表中SALARY(工资)大于等于30000的数据,删除删除的数据插入COMPANY1表,实现将COMPANY表数据转移到COMPANY1表中:
创建表公司1(( ID INT PRIMARY KEY NOT NULL,, NAME TEXT NOT NULL,, AGE INT NOT NULL,, 地址字符(50),(50 ), 工资真实 );); 与moved_rows AS(( 从公司删除 哪里 工资> = 30000> = 30000 返回** )) 插入到COMPANY1(选择*从moved_rows(选择* 来自moved_rows
得到结果如下:
插入0 30 3
此时,CAMPANY表和CAMPANY1表的数据如下:
runoobdb =#SELECT * FROM COMPANY;=#SELECT * FROM COMPANY ; id | 名称| 年龄| 地址| 薪水| 名称 | 年龄| 地址 | 薪水 ---- + ------- + ----- + ------------ + ------------ + ------- + ----- + ------------ + -------- 1 | 保罗| 32 | 加利福尼亚| 200001 | 保罗| 32 | 加利福尼亚| 20000 2 | 艾伦| 25 | 德州| 150002 | 艾伦| 25 | 德州| 15000 3 | 泰迪 23 | 挪威| 200003 | 泰迪| 23 | 挪威| 20000 7 | 詹姆斯| 24 | 休斯顿| 100007 | 詹姆斯| 24 | 休斯顿| 10000 (4列)(4 行) runoobdb =#SELECT * FROM COMPANY1; id | 名称| 年龄| 地址| 薪水 ---- + ------- + ----- + ------------- + -------- 4 | 马克| 25 | 富蒙德| 65000 5 | 大卫| 27 | 德州| 85000 6 | 金| 22 | 南厅| 45000 (3列)