• SQL:With recursive 递归用法


    With Recursive as

    有两种递归字段n的声明写法,第一种是在with… as 中声明需要递归的字段,第二种是在sql语句中第一段的初始值内声明变量。
    WITH RECURSIVE cte (n) AS
    ( select 初始值 from table
    union all
    select 递归内容 from cte where (终止条件)
    )
    这里注意 递归内容中选择的表格是cte,引用的是临时的递归表格。

    # 在with... as 中声明需要递归的字段
    WITH RECURSIVE cte (n) AS  
    (
      SELECT 1  #初始值
      UNION ALL
      SELECT n + 1 FROM cte WHERE n < 5  #递归内容 from cte 表
    )
    SELECT * FROM cte;
    
    #输出结果
    +------+
    | n    |
    +------+
    |    1 |
    |    2 |
    |    3 |
    |    4 |
    |    5 |
    +------+
    
    
    
    # 在第一段的初始值代码中声明
    WITH RECURSIVE cte AS
    (
      SELECT 1 AS n, CAST('abc' AS CHAR(20)) AS str
      UNION ALL
      SELECT n + 1, CONCAT(str, str) FROM cte WHERE n < 3
    )
    SELECT * FROM cte;
    
    #输出结果
    +------+--------------+
    | n    | str          |
    +------+--------------+
    |    1 | abc          |
    |    2 | abcabc       |
    |    3 | abcabcabcabc |
    +------+--------------+
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    注:hive 目前不支持

    参考链接:https://dev.mysql.com/doc/refman/8.0/en/with.html#common-table-expressions-recursive

    题目一

    Column NameType
    customer_idint
    customer_namevarchar
    customer_id 是该表主键.
    该表第一行包含了顾客的名字和id.

    写一个 SQL 语句, 找到所有遗失的顾客id. 遗失的顾客id是指那些不在 Customers 表中, 值却处于 1 和表中最大 customer_id 之间的id.
    注意: 最大的 customer_id 值不会超过 100.

    返回结果按 ids 升序排列

    查询结果格式如下例所示。

    输入:
    Customers 表:

    customer_idcustomer_name
    1Alice
    4Bob
    5Charlie

    输出:

    ids
    2
    3

    **解释:**表中最大的customer_id是5, 所以在范围[1,5]内, ID2和3从表中遗失.

    拆解思路

    题目很简单,主要是需要生成一个1到最大值的临时表,然后从里面找出不再customer 表格里的id。

    本题难点在于如何生成这个临时表。

    with recursive t1 as (
        select 1 as n
        union all
        select n + 1 from t1 where n < 100
    )
    
    select n as ids
    from t1
    where 
        n <= (select max(customer_id)from Customers)
        and n not in (select customer_id from Customers)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/find-the-missing-ids

    题目二: 向CEO汇报的所有员工

    员工表:Employees

    Column NameType
    employee_idint
    employee_namevarchar
    manager_idint

    employee_id 是这个表的主键。
    这个表中每一行中,employee_id 表示职工的 ID,employee_name 表示职工的名字,manager_id 表示该职工汇报工作的直线经理。
    这个公司 CEO 是 employee_id = 1 的人。

    拆解思路

    # Write your MySQL query statement below
    with recursive temp as (
        select e.employee_id from Employees e where e.employee_id!=1 and manager_id=1
        union all 
        select e.employee_id from Employees e join temp t on t.employee_id=e.manager_id
    )
    select * from temp 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    来源:力扣(LeetCode)
    链接:https://leetcode.cn/problems/all-people-report-to-the-given-manager

  • 相关阅读:
    小索引大力量,记一次explain的性能优化经历
    计算机专业的就业情况如何?
    js基础笔记学习197-字符串得方法3
    MyBatis Plus详细教程
    n个数的全排列
    三十而立技术er的进击之路
    Docker常用命令,你该掌握啦!
    Renesas:如何指定段(地址)存放数据
    【vue】主分支外的一些知识点
    MyBatis-Plus配置
  • 原文地址:https://blog.csdn.net/WHYbeHERE/article/details/125440856