【mysql8的一个利器, CTE查询】

今天因为一个比较头疼的mysql查询问题, 去Stack Overflow提问, 然后底下有人答复说既然用了mysql8, 不要用子查询, 直接用CTE查询. CTE查询是啥, 我直接百度了下, 然后发现, 这玩意太好用了, 但是说实话, 我可以肯定大多数人基本都不会去了解这些新出的功能,毕竟经手的项目大多数几年前的项目了,版本低. 但是说不定也有和我一样正在用mysql8版本的朋友, 所以分享出来

  • 1、MySQL8.0之前,进行复杂查询时需要使用子查询来实现,SQL语句不仅语句复杂性能低,而且不够清晰。CTE的出现简化了复杂查询语句的编写,提高了SQL性能。

  • 2、与子查询或者派生查询相比,CTE可以重用上次的查询结果即查询一次即可,同时,CTE可以相互引用

语法

递归查询语法

WITH RECURSIVE 别名 AS (
    初始化语句  -- anchor member
    UNION ALL
    后续递归语句 -- 引用CTE名称的递归成员
SELECT * FROM 别名; 

普通

WITH RECURSIVE 别名 AS (
    查询语句  -- anchor member
)     
SELECT * FROM 别名; 

使用

首先看看两种情况的使用

普通

普通情况下, 不要加RECURSIVE关键字,
比如我们有个查询, A JOIN B 且条件a, 然后A JOIN C 且条件b, 最后union all:

select *
from A join B on A.id = B.aid
union all
select *
from A join C on A.id = C.aid

那我们可以这样写,CTE可以复用的方法

with 
  a as (select * from A),
  b as (select * from a join B on a.id = B.aid),
  c as (select * from a join C on a.id = C.aid)
select * from b union all select * from c;

可以看到我们的A不需要查2次了

递归循环

这种方式可以用for循环来理解

for(int i=1,i<5;i++){
}
WITH RECURSIVE 别名 AS (
    初始化语句  -- anchor member
    UNION ALL
    后续递归语句 -- 引用CTE名称的递归成员
SELECT * FROM 别名; 
  • 初始化语句, 也就是i=1
  • 后续递归语句, 相当于i<5和i++

举个栗子:

WITH RECURSIVE cte_count (n) 
AS (
      SELECT 1
      UNION ALL
      SELECT n + 1       FROM cte_count       WHERE n < 3
    )
SELECT n 
FROM cte_count; 

这个就表示

  1. 先生成一个1, 放到cte_count表
  2. 在此基础上, 循环执行SELECT n + 1 FROM cte_count放入表里, 同时n<3表示结束条件
  3. 最后查询展示
+---+
| n |
+---+
| 1 |
| 2 |
| 3 |
+---+
3 rows in set (0.01 sec)

大概就是这么个东西

以上都是基础的使用, 熟悉了以后可以组合, 感觉完全可以替代原来的子查询

你可能感兴趣的:(数据库,数据库,mysql)