本文实例讲述了mysql8 公用表表达式CTE的使用方法。分享给大家供大家参考,具体如下:

公用表表达式CTE就是命名的临时结果集,作用范围是当前语句。

说白点你可以理解成一个可以复用的子查询,当然跟子查询还是有点区别的,CTE可以引用其他CTE,但子查询不能引用其他子查询。

一、cte的语法格式:

with_clause:

WITH [RECURSIVE]

cte_name [(col_name [, col_name] ...)] AS (subquery)

[, cte_name [(col_name [, col_name] ...)] AS (subquery)] ...

二、哪些地方可以使用with语句创建cte

1、select, update,delete 语句的开头

WITH ... SELECT ...

WITH ... UPDATE ...

WITH ... DELETE ...

2、在子查询的开头或派生表子查询的开头

SELECT ... WHERE id IN (WITH ... SELECT ...) ...

SELECT * FROM (WITH ... SELECT ...) AS dt ...

3、紧接SELECT,在包含 SELECT声明的语句之前

INSERT ... WITH ... SELECT ...

REPLACE ... WITH ... SELECT ...

CREATE TABLE ... WITH ... SELECT ...

CREATE VIEW ... WITH ... SELECT ...

DECLARE CURSOR ... WITH ... SELECT ...

EXPLAIN ... WITH ... SELECT ...

三、我们先建个表,准备点数据

CREATE TABLE `menu` (

`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',

`name` varchar(32) DEFAULT '' COMMENT '名称',

`url` varchar(255) DEFAULT '' COMMENT 'url地址',

`pid` int(11) DEFAULT '0' COMMENT '父级ID',

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

插入点数据:

INSERT INTO `menu` (`id`, `name`, `url`, `pid`) VALUES ('1', '后台管理', '/manage', '0');

INSERT INTO `menu` (`id`, `name`, `url`, `pid`) VALUES ('2', '用户管理', '/manage/user', '1');

INSERT INTO `menu` (`id`, `name`, `url`, `pid`) VALUES ('3', '文章管理', '/manage/article', '1');

INSERT INTO `menu` (`id`, `name`, `url`, `pid`) VALUES ('4', '添加用户', '/manage/user/add', '2');

INSERT INTO `menu` (`id`, `name`, `url`, `pid`) VALUES ('5', '用户列表', '/manage/user/list', '2');

INSERT INTO `menu` (`id`, `name`, `url`, `pid`) VALUES ('6', '添加文章', '/manage/article/add', '3');

INSERT INTO `menu` (`id`, `name`, `url`, `pid`) VALUES ('7', '文章列表', '/manage/article/list', '3');

四、非递归CTE

这里查询每个菜单对应的直接上级名称,通过子查询的方式。

select m.*, (select name from menu where id = m.pid) as pname from menu as m;

这里换成用cte完成上面的功能

with cte as (

select * from menu

)

select m.*, (select cte.name from cte where cte.id = m.pid) as pname from menu as m;

上面的示例并不是很好,只是用来演示cte的使用。你只需要知道 cte 就是一个可复用的结果集就好了。

相比较某些子查询,cte 的效率会更高,因为非递归的 cte 只会查询一次并复用。

cte 可以引用其他 cte 的结果,比如下面的语句,cte2 就引用了 cte1 中的结果。

with cte1 as (

select * from menu

), cte2 as (

select m.*, cte1.name as pname from menu as m left join cte1 on m.pid = cte1.id

)

select * from cte2;

五、递归CTE

递归cte是一种特殊的cte,其子查询会引用自身,with子句必须以 with recursive 开头。

cte递归子查询包括两部分:seed 查询 和 recursive 查询,中间由union [all] 或 union distinct 分隔。

seed 查询会被执行一次,以创建初始数据子集。

recursive 查询会被重复执行以返回数据子集,直到获得完整结果集。当迭代不会生成任何新行时,递归会停止。

with recursive cte(n) as (

select 1

union all

select n + 1 from cte where n < 10

)

select * from cte;

上面的语句,会递归显示10行,每行分别显示1-10数字。

递归的过程如下:

1、首先执行 select 1 得到结果 1, 则当前 n 的值为 1。

2、接着执行 select n + 1 from cte where n < 10,因为当前 n 为 1,所以where条件成立,生成新行,select n + 1 得到结果 2,则当前 n 的值为 2。

3、继续执行 select n + 1 from cte where n < 10,因为当前 n 为 2,所以where条件成立,生成新行,select n + 1 得到结果 3,则当前 n 的值为 3。

4、一直递归下去

5、直到当 n 为 10 时,where条件不成立,无法生成新行,则递归停止。

对于一些有上下级关系的数据,通过递归cte就可以很好的处理了。

比如我们要查询每个菜单到顶级菜单的路径

with recursive cte as (

select id, name, cast('0' as char(255)) as path from menu where pid = 0

union all

select menu.id, menu.name, concat(cte.path, ',', cte.id) as path from menu inner join cte on menu.pid = cte.id

)

select * from cte;

递归的过程如下:

1、首先查询出所有 pid = 0 的菜单数据,并设置path 为 '0',此时cte的结果集为 pid = 0 的所有菜单数据。

2、执行 menu inner join cte on menu.pid = cte.id ,这时表 menu 与 cte (步骤1中获取的结果集) 进行内连接,获取菜单父级为顶级菜单的数据。

3、继续执行 menu inner join cte on menu.pid = cte.id,这时表 menu 与 cte (步骤2中获取的结果集) 进行内连接,获取菜单父级的父级为顶级菜单的数据。

4、一直递归下去

5、直到没有返回任何行时,递归停止。

查询一个指定菜单所有的父级菜单

with recursive cte as (

select id, name, pid from menu where id = 7

union all

select menu.id, menu.name, menu.pid from menu inner join cte on cte.pid = menu.id

)

select * from cte;

希望本文所述对大家MySQL数据库计有所帮助。

mysql cte_mysql8 公用表表达式CTE的使用方法实例分析相关推荐

  1. mysql cte 语法,mysql8 公用表表达式CTE的使用方法实例分析

    本文实例讲述了mysql8 公用表表达式cte的使用方法.分享给大家供大家参考,具体如下: 公用表表达式cte就是命名的临时结果集,作用范围是当前语句. 说白点你可以理解成一个可以复用的子查询,当然跟 ...

  2. T-SQL查询进阶--详解公用表表达式(CTE)

    简介 对于SELECT查询语句来说,通常情况下,为了使T-SQL代码更加简洁和可读,在一个查询中引用另外的结果集都是通过视图而不是子查询来进行分解的.但是,视图是作为系统对象存在数据库中,那对于结果集 ...

  3. 详解公用表表达式(CTE)

    简介 对于SELECT查询语句来说,通常情况下,为了使T-SQL代码更加简洁和可读,在一个查询中引用另外的结果集都是通过视图而不是子查询来进行分解的.但是,视图是作为系统对象存在数据库中,那对于结果集 ...

  4. 公用表表达式(CTE)WITH:树型查询、更新

    转自http://msdn.microsoft.com/zh-cn/library/ms175972(SQL.100).aspx 指定临时命名的结果集,这些结果集称为公用表表达式 (CTE). 语法: ...

  5. 在Sql Server 2005使用公用表表达式CTE简化复杂的查询语句

    公用表表达式CTE是Sql Server 2005引入的一种新的表表达式.CTE在许多方面都类似于派生表.逻辑上CTE是一个临时结果集,它仅仅存在于它发生的语句中.您可以在SELECT.INSERT. ...

  6. SQL Server中公用表表达式 CTE 递归的生成帮助数据,以及递归的典型应用

    原文: SQL Server中公用表表达式 CTE 递归的生成帮助数据,以及递归的典型应用 本文出处:http://www.cnblogs.com/wy123/p/5960825.html 我们在做开 ...

  7. cte mysql_mysql8 公用表表达式CTE的使用

    公用表表达式CTE就是命名的临时结果集,作用范围是当前语句. 说白点你可以理解成一个可以复用的子查询,当然跟子查询还是有点区别的,CTE可以引用其他CTE,但子查询不能引用其他子查询. 一.cte的语 ...

  8. T-SQL之公用表表达式(CTE)

    题外话: 以前也写过几篇,后来总算觉得写得不够好,写了点又删了点,最后一直没有东西留下来,随着时间的流逝,几乎没有积累.最近在看T-SQL相关的书,结合工作中遇到的问题,我打算写点东西来记录我的学习经 ...

  9. as my sql 后面加表达式_SQL.WITH AS.公用表表达式(CTE)(转)

    一.WITH AS的含义 WITH AS短语,也叫做子查询部分(subquery factoring),可以让你做很多事情,定义一个SQL片断,该SQL片断会被整个SQL语句所用到.有的时候,是为了让 ...

最新文章

  1. 《从零开始学Swift》学习笔记(Day 47)——final关键字
  2. matlab 转换 tfrecord,训练数据集与TFRecord互相转换的两种方式
  3. 【RAY TRACING THE REST OF YOUR LIFE 超详解】 光线追踪 3-5 random direction ONB
  4. 如何优化代码和RAM大小
  5. jquery 获取键值对中最大值_jQuery的AJAX发送数据键值对
  6. java optional用法_2019年 Java 调查报告:“被取代”是不存在的!
  7. 斜齿轮受力计算:理论计算virtual.lab motion 仿真
  8. mysql 远程主机强迫关闭了一个现有的连接_MySQL的explain优化(3)
  9. python兔子和獾_少儿编程分享:手把手教你用PYTHON编写兔獾大作战(三)
  10. Abp vnext Web应用程序开发教程 9 —— 作者:用户界面
  11. redhat6.3下安装ORACLE11.2.3RAC
  12. 爬虫调用百度翻译API
  13. 计算两个经纬度之间的距离软件_小程序使用腾讯位置服务计算两地之间的距离(有源码)...
  14. MOSS架构和共享服务(Shared Service)
  15. 分享一份自己整理的PPT--数据分析师的业务流程和常规思维
  16. 目标跟踪入门篇—相关滤波
  17. 【Linux】tar命令各参数详解
  18. 【大数据时代】前端数据可视化利器D3.js、highcharts、echarts(毕设调研)
  19. html怎样 做二级菜单,HTML制作二级下拉菜单的方法步骤
  20. html产生圆点列表符号的列表,HTML 测验

热门文章

  1. WPS WORD内表格文字底部对齐
  2. 如何使用手刹解密和翻录DVD
  3. 14树型软件辅助设计
  4. 惠普服务器启动时主板显示40,HP 600G1 DM小主机低温不能启动,开机无显电源键红灯伴4长声报警...
  5. 发布一个最新版coos核心代码
  6. 150 元低成本改装家里的门锁,抓好软件硬件,向物联网出发
  7. tomcat隐藏版本号
  8. 物联网时代下的三巨头:美的的势、格力的专、海尔的局
  9. java阳历农历互相转换
  10. Redis 哨兵集群实现高可用