mysql8.0后支持递归公用表达式CTE,递归CTE子句中必须包含两个部分,一个是种子查询(不可引用自身),另一个是递归查询,这两个子查询可以通过 UNION、UNION ALL或UNION DISTINCT 连接在一起。
注意:种子SELECT只会执行一次,并得到初始的数据子集,而递归SELECT是会重复执行直到没有新的行产生为止,最终将所有的结果集都查询出来,这对于深层查询(如具有父子关系的查询)是非常有用的。示例:查询公司的组织架构数据,查询管理层级。
创建表:
CREATE TABLE emp(插入数据:
id INT PRIMARY KEY NOT NULL,
name VARCHAR(100) NOT NULL,
manager_id INT NULL,
INDEX (manager_id),
FOREIGN KEY (manager_id) REFERENCES employees_mgr
(id)
);
INSERT INTO emp VALUES递归查询:
(333, "总经理", NULL),
(198, "副总1", 333),
(692, "副总2", 333),
(29, "主任1", 198),
(4610, "职员1", 29),
(72, "职员2", 29),
(123, "主任2", 692);
WITH RECURSIVE test(id, name, path)结果如下:
AS
(
SELECT id, name, CAST(id AS CHAR(200))
FROM emp WHERE manager_id IS NULL
UNION ALL
SELECT e.id, e.name, CONCAT(ep.path, ',', e.id)
FROM test AS ep JOIN emp AS e ON ep.id = e.manager_id
)SELECT * FROM test ORDER BY path;
+------+---------+-----------------+
| id | name | path |
+------+---------+-----------------+
| 333 | 总经理| 333 |
| 198 | 副总1| 333,198 |
| 29 | 主任1| 333,198,29 |
| 4610 | 职员1| 333,198,29,4610 |
| 72 | 职员2| 333,198,29,72 |
| 692 | 副总2| 333,692 |
| 123 | 主任2| 333,692,123 |
网友回复