一、CTE
概念:
MySQL的CTE是在MySQL8.0版本开始支持的,公用表表达式是一个命名的临时结果集,仅在单个SQL语句(例如select、insert、delete和update)的执行范围内存在
意义:
1> MySQL8.0之前,进行复杂查询时需要使用子查询来实现,SQL语句不仅语句复杂性能低,而且不够清晰。CTE的出现简化了复杂查询语句的编写,提高了SQL性能。
2> 与子查询或者派生查询相比,CTE可以重用上次的查询结果即查询一次即可,同时,CTE可以相互引用。例如:
WITH
d1 AS (SELECT ... FROM ...),
d2 AS (SELECT ... FROM d1 ... )
SELECT * FROM d1, d2 ...
语法:
WITH cte_name (column_list) AS (
cte_query
)
SELECT * FROM cte_name;
说明:
cte_name: 必填。CTE的名称,不能与当前with子句中的其他CTE的名称相同。
column_list: 可选。查询中的列数必须与column_list中的列数相同。 如果省略column_list,将使用cte中查询语句中使用的列。
**cte_query:**必填。一个select语句。select的结果集用于填充CTE。
**注意:**多个cte查询语句之间用逗号分隔。
二、举例分析
原来写法:
sql
-- 原来写法:
select *
from (
select a.key, b.value
from (select * from src where key is not null ) a
join (select * from src2 where value > 0 ) b
on a.key = b.key
) T1
union all
select *
from (
select a.key, c.value
from (select * from src where key is not null ) a
left outer join (select * from src3 where value > 0 ) c
on a.key = c.key and c.key is not null
)T2;
顶层的union两侧各为一个join,join的左表是相同的查询语句。通过写子查询的方式,只能重复这段代码。使用CTE的方式重写以上语句,命令示例如下:
sql
with
a as (select * from src where key is not null),
b as (select * from src2 where value > 0),
c as (select * from src3 where value > 0),
T1 as (select a.key, b.value from a join b on a.key=b.key),
T2 as (select a.key,c.value from a left outer join c on a.key=c.key and c.key is not null)
select * from T1 union all select * from T2;
小小举例:
sql
-- 测试CTE
WITH aa AS(
SELECT *
FROM stu_score
)
SELECT * FROM aa;