Common table expression(公共表表达式)简称CTE,由SQL:1999标准引入,CTE可以看成是一个临时创建的视图,生命周期仅限于当前语境,一旦CTE被创建,可以将其当成一般的表,大部分基于表的操作都可以运用于CTE。
目前支持CTE的数据库有Teradata, DB2, Firebird, Microsoft SQL Server, Oracle (with recursion since 11g release 2), PostgreSQL (since 8.4), MariaDB (since 10.2), SQLite (since 3.8.3), HyperSQL and H2 (experimental), MySQL8.0。
1、下面是创建CTE的语法结构:
WITH expression_name (colum1,colum2,...,columN) AS ( CTE_query_definition ) CTE_query_definition表示一个SELECT语句,它产生的结果集用于填充CTE。这个SELECT语句与定义视图时的SELECT语句一样,必须满足必要的条件。不能使用一个CTE(公共表表达式)来定义另一个CTE(公共表表达式)。如果CTE_query_definition有多个查询语句,必须使用UNION ALL,UNION,EXCEPT,或者INTERSECT其中的一个连接词来连接 CTE可用于 1.创建递归查询 2.在同一语句中多次引用生成的表 3.减少子查询和表变量,提高执行效率 CTE优点: 1.使用 CTE 可以提高可读性和轻松维护复杂查询。同时,一般情况CTE要比表变量的效率高。 2.可以用来定义一个SQL片断,该SQL片断会被整个SQL语句用到。有时为了提高SQL语句的可读性,也会用在UNION ALL的不同部分,作为提供数据的部分。
2、普通用法示例
WITH cte_emp as (SELECT * from emp where empno=7566) SELECT * from cte_emp;
–可以写多个CTE,使用逗号分隔
WITH cte_emp as (SELECT * from emp where empno=7566), cte_dept as (select * from dept) SELECT * from cte_emp,cte_dept where cte_emp.deptno=cte_dept.deptno;
3、递归CTE
–在HGDB使用递归CTE,需要添加关键词RECURSIVE,并列出每列的名称
WITH RECURSIVE cte_emp(empno,ename,job,mgr,hiredate,sal,comm,deptno) as ( SELECT * from emp where empno=7566 union all select emp.empno,emp.ename,emp.job,emp.mgr,emp.hiredate,emp.sal,emp.comm,emp.deptno from emp,cte_emp where emp.mgr=cte_emp.empno ) select * from cte_emp;
通过上图可以明白查询时获取数据的过程,“SELECT * from emp where empno=7566”获取7566的资料,然后根据“emp.mgr=cte_emp.empno”查询7566管理的人员7902和7788,重复“emp.mgr=cte_emp.empno”过程,获取7902和7788管理的人员7369和7876,因为7369和7876没有管理的员工,递归过程到此结束。