千家信息网

MySQL 8.0新特性--CTE(一)

发表于:2024-10-17 作者:千家信息网编辑
千家信息网最后更新 2024年10月17日,1、CTE简介MySQL从8.0开始支持CTE,慢慢地向Oracle学习,CTE确实是个很好用的东西,特别是针对OLAP类型的SQL,可以大大简化,优化SQL.那么什么是CTE呢?个人理解:CTE(c
千家信息网最后更新 2024年10月17日MySQL 8.0新特性--CTE(一)

1、CTE简介

MySQL从8.0开始支持CTE,慢慢地向Oracle学习,CTE确实是个很好用的东西,特别是针对OLAP类型的SQL,可以大大简化,优化SQL.

那么什么是CTE呢?

个人理解:CTE(common table expression)是一个临时的结果集,类似一个函数,一旦定义好,可以多次调用。


2、CTE语法

with_clause:    WITH [RECURSIVE]        cte_name [(col_name [, col_name] ...)] AS (subquery)        [, cte_name [(col_name [, col_name] ...)] AS (subquery)] ...

(1)列别名可以在不同的位置定义

mysql> WITH cte (col1, col2) AS    -> (    ->   SELECT 1, 2    ->   UNION ALL    ->   SELECT 3, 4    -> )    -> SELECT col1, col2 FROM cte;+------+------+| col1 | col2 |+------+------+|    1 |    2 ||    3 |    4 |+------+------+2 rows in set (0.00 sec)等价与:mysql> WITH cte AS    -> (    ->   SELECT 1 AS col1, 2 AS col2    ->   UNION ALL    ->   SELECT 3, 4    -> )    -> SELECT col1, col2 FROM cte;+------+------+| col1 | col2 |+------+------+|    1 |    2 ||    3 |    4 |+------+------+2 rows in set (0.00 sec)

(2) CTE用在Select操作

mysql> create table t1(a int,b int);mysql> insert into t1 values(1,1),(2,2),(3,3);mysql> with t as       (select a+2 c,b from t1)        select c,b from t;+------+------+| c    | b    |+------+------+|    3 |    1 ||    4 |    2 ||    5 |    3 |+------+------+3 rows in set (0.00 sec)

(3)CTE用在DML操作

mysql> with t as (select a+2 as a,b from t1) update t1,t set t1.a=t.a+10 where t1.a=t.a;mysql> select * from t1;+------+------+| a    | b    |+------+------+|    1 |    1 ||    2 |    2 ||   13 |    3 |+------+------+3 rows in set (0.00 sec)mysql> with t as (select a+2 as a,b from t1) delete t1 from t1,t where t1.a=t.a;mysql> select * from t1;+------+------+| a    | b    |+------+------+|    1 |    1 ||    2 |    2 |+------+------+2 rows in set (0.00 sec)mysql> insert into t1 with t as (select 10*a as a,b from t1) select * from t;mysql> select * from t1;+------+------+| a    | b    |+------+------+|    1 |    1 ||    2 |    2 ||    3 |    3 ||   10 |    1 ||   20 |    2 ||   30 |    3 |+------+------+6 rows in set (0.00 sec)


3、CTE可以优化SQL

(1)下面第一条SQL可以改写成如下两种CTE简化形式

mysql> select count(*) from employees e1        left join (select * from employees) e2 on e1.emp_no=e2.emp_no        left join (select * from employees) e3 on e2.emp_no=e3.emp_no;       mysql> with e2 as (select * from employees),            e3 as (select * from employees)             select count(*) from employees e1             left join e2 on e1.emp_no=e2.emp_no             left join e3 on e2.emp_no=e3.emp_no;            mysql> with e as(select * from employees) select count(*) from employees e1        left join e e2 on e1.emp_no=e2.emp_no        left join e e3 on e2.emp_no=e3.emp_no;


(2)CTE的本质是子查询,所以子查询的一些特性都适用,如子查询合并。

mysql> desc with e as(select /*+ set_var(optimizer_switch='derived_merge=off')*/ * from employees)    -> select count(*) from employees e1    -> left join e e2 on e1.emp_no=e2.emp_no    -> left join e e3 on e2.emp_no=e3.emp_no;+----+-------------+------------+------------+-------+---------------+-------------+---------+------------------+--------+----------+-------------+| id | select_type | table      | partitions | type  | possible_keys | key         | key_len | ref              | rows   | filtered | Extra       |+----+-------------+------------+------------+-------+---------------+-------------+---------+------------------+--------+----------+-------------+|  1 | PRIMARY     | e1         | NULL       | index | NULL          | PRIMARY     | 4       | NULL             | 299512 |   100.00 | Using index ||  1 | PRIMARY     |  | NULL       | ref   |    |  | 4       | testdb.e1.emp_no |     10 |   100.00 | NULL        ||  1 | PRIMARY     |  | NULL       | ref   |    |  | 4       | e2.emp_no        |     10 |   100.00 | NULL        ||  2 | DERIVED     | employees  | NULL       | ALL   | NULL          | NULL        | NULL    | NULL             | 299512 |   100.00 | NULL        |+----+-------------+------------+------------+-------+---------------+-------------+---------+------------------+--------+----------+-------------+4 rows in set, 2 warnings (0.00 sec)


(3)CTE可以起到减少插入临时表数据,优化SQL的作用

mysql> flush status;Query OK, 0 rows affected (0.02 sec)mysql> select /*+ set_var(optimizer_switch='derived_merge=off')*/ * from    -> (select * from t_group) t1    -> join (select * from t_group) t2    -> on t1.emp_no=t2.emp_no;+--------+---------+------------+------------+--------+---------+------------+------------+| emp_no | dept_no | from_date  | to_date    | emp_no | dept_no | from_date  | to_date    |+--------+---------+------------+------------+--------+---------+------------+------------+|  22744 | d006    | 1986-12-01 | 9999-01-01 |  22744 | d006    | 1986-12-01 | 9999-01-01 ||  24007 | d005    | 1986-12-01 | 9999-01-01 |  24007 | d005    | 1986-12-01 | 9999-01-01 ||  30970 | d005    | 1986-12-01 | 2017-03-29 |  30970 | d005    | 1986-12-01 | 2017-03-29 ||  31112 | d002    | 1986-12-01 | 1993-12-10 |  31112 | d002    | 1986-12-01 | 1993-12-10 ||  40983 | d005    | 1986-12-01 | 9999-01-01 |  40983 | d005    | 1986-12-01 | 9999-01-01 ||  46554 | d008    | 1986-12-01 | 1992-05-27 |  46554 | d008    | 1986-12-01 | 1992-05-27 ||  48317 | d008    | 1986-12-01 | 1989-01-11 |  48317 | d008    | 1986-12-01 | 1989-01-11 ||  49667 | d007    | 1986-12-01 | 9999-01-01 |  49667 | d007    | 1986-12-01 | 9999-01-01 ||  50449 | d005    | 1986-12-01 | 9999-01-01 |  50449 | d005    | 1986-12-01 | 9999-01-01 ||  10004 | d004    | 1986-12-01 | 9999-01-01 |  10004 | d004    | 1986-12-01 | 9999-01-01 |+--------+---------+------------+------------+--------+---------+------------+------------+10 rows in set (0.00 sec)mysql> show status like '%handler_write%';+---------------+-------+| Variable_name | Value |+---------------+-------+| Handler_write | 20    |+---------------+-------+1 row in set (0.00 sec)mysql> flush status;Query OK, 0 rows affected (0.02 sec)mysql> with t as(select /*+ set_var(optimizer_switch='derived_merge=off')*/ * from t_group)    -> select * from t t1    -> join t t2 on t1.emp_no=t2.emp_no;+--------+---------+------------+------------+--------+---------+------------+------------+| emp_no | dept_no | from_date  | to_date    | emp_no | dept_no | from_date  | to_date    |+--------+---------+------------+------------+--------+---------+------------+------------+|  22744 | d006    | 1986-12-01 | 9999-01-01 |  22744 | d006    | 1986-12-01 | 9999-01-01 ||  24007 | d005    | 1986-12-01 | 9999-01-01 |  24007 | d005    | 1986-12-01 | 9999-01-01 ||  30970 | d005    | 1986-12-01 | 2017-03-29 |  30970 | d005    | 1986-12-01 | 2017-03-29 ||  31112 | d002    | 1986-12-01 | 1993-12-10 |  31112 | d002    | 1986-12-01 | 1993-12-10 ||  40983 | d005    | 1986-12-01 | 9999-01-01 |  40983 | d005    | 1986-12-01 | 9999-01-01 ||  46554 | d008    | 1986-12-01 | 1992-05-27 |  46554 | d008    | 1986-12-01 | 1992-05-27 ||  48317 | d008    | 1986-12-01 | 1989-01-11 |  48317 | d008    | 1986-12-01 | 1989-01-11 ||  49667 | d007    | 1986-12-01 | 9999-01-01 |  49667 | d007    | 1986-12-01 | 9999-01-01 ||  50449 | d005    | 1986-12-01 | 9999-01-01 |  50449 | d005    | 1986-12-01 | 9999-01-01 ||  10004 | d004    | 1986-12-01 | 9999-01-01 |  10004 | d004    | 1986-12-01 | 9999-01-01 |+--------+---------+------------+------------+--------+---------+------------+------------+10 rows in set, 1 warning (0.00 sec)mysql> show status like '%handler_write%';+---------------+-------+| Variable_name | Value |+---------------+-------+| Handler_write | 10    |+---------------+-------+1 row in set (0.00 sec)


CTE除了一般功能外,还可以实现递归一些复杂SQL需求,参考MySQL 8.0新特性--CTE(二)

参考链接

13.2.13 WITH Syntax (Common Table Expressions)


查询 特性 参考 不同 复杂 东西 个人 位置 作用 函数 别名 功能 形式 数据 本质 等价 简介 类型 结果 语法 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 怀旧服服务器可以直接买么 java游戏服务器开发 岁学软件开发晚不晚 数据库技术03139真题 江苏腾轩网络技术有限公司 黑哥网络安全之前是干什么的 信息网络技术要学什么 制作网络安全海报活动简报 越秀区质量网络技术开发价格多少 社会力量参与救灾数据库 端游原神怎么查看服务器 九星天辰诀在服务器安装教程 网鱼杀毒服务器管理 软件开发项目管理培训记录 青岛大型互联网科技公司 软件开发用的原型是什么 软件开发哪一阶段需要流程图 局域网内2台电脑都加了域服务器 海曙直销软件开发 网络安全干部职工要求 中学生网络安全班会 软件开发人力外包属于劳务费 正宗笔画输入法软件开发商 著名软件开发者被抓 软件开发定制工作室需要什么 服务器磁盘备份 服务器系统安全与维护 论文 xcode 服务器 数据库取证基础 给软件开发公司设计一个激励方案
0