首页 > 数据库 > 数据库开发技术 > 五种主流数据库:递归查询

WITH cte_name(col1, col2, ...) AS (
subquery
)
SELECT * FROM cte_name;
WITH t(n) AS (
SELECT 1
)
SELECT n
FROM t;
n
-
1
WITH t1(n) AS (
SELECT 1
),
t2(m) AS (
SELECT n+1
FROM t1
)
SELECT t1.n, t2.m
FROM t1
CROSS JOIN t2;
n|m
-|-
1|2
SELECT dept_cost.dept_name AS "部门名称",
dept_cost.total AS "部门成本",
detp_avg_cost.avg_total AS "平均成本"
FROM (SELECT dept_name, SUM(salary*12 + COALESCE(bonus, 0)) total
FROM employee e
JOIN department d ON (e.dept_id = d.dept_id)
GROUP BY dept_name
) dept_cost
JOIN (SELECT SUM(total)/COUNT(*) avg_total
FROM (SELECT dept_name, SUM(salary*12 + COALESCE(bonus, 0)) total
FROM employee e
JOIN department d
ON (e.dept_id = d.dept_id)
GROUP BY dept_name
) dept_cost
) detp_avg_cost
ON (dept_cost.total > detp_avg_cost.avg_total);
部门名称 |部门成本 |平均成本
--------|---------|-------------
行政管理部|990000.00|601420.000000
研发部 |824400.00|601420.000000
WITH dept_cost(dept_name, total) AS
(SELECT dept_name, SUM(salary*12 + COALESCE(bonus, 0))
FROM employee e
JOIN department d ON (e.dept_id = d.dept_id)
GROUP BY dept_name
),
detp_avg_cost(avg_total) AS (
SELECT SUM(total)/COUNT(*) avg_total
FROM dept_cost
)
SELECT dept_cost.dept_name AS "部门名称",
dept_cost.total AS "总成本",
detp_avg_cost.avg_total AS "平均成本"
FROM dept_cost
JOIN detp_avg_cost
ON (dept_cost.total > detp_avg_cost.avg_total);
WITH RECURSIVE cte_name AS(
cte_query_initial -- 初始化部分
UNION [ALL]
cte_query_iterative -- 递归部分
) SELECT * FROM cte_name;
-- MySQL、PostgreSQL 以及 SQLite
WITH RECURSIVE t(n) AS
(
SELECT 1
UNION ALL
SELECT n + 1 FROM t WHERE n < 10
)
SELECT n FROM t;
-- Oracle、Microsoft SQL Server
WITH t(n) AS
(
SELECT 1
UNION ALL
SELECT n + 1 FROM t WHERE n < 10
)
SELECT n FROM t;
n
--
1
2
3
...
9
10
-- MySQL
WITH RECURSIVE employee_path (emp_id, emp_name, path) AS
(
SELECT emp_id, emp_name, emp_name AS path
FROM employee
WHERE manager IS NULL
UNION ALL
SELECT e.emp_id, e.emp_name,
CONCAT(ep.path, '->', e.emp_name)
FROM employee_path ep
JOIN employee e ON ep.emp_id = e.manager
)
SELECT emp_name AS "员工姓名", PATH AS "管理路径"
FROM employee_path
ORDER BY emp_id;
员工姓名|管理路径
-------|----------
刘备 |刘备
关羽 |刘备->关羽
张飞 |刘备->张飞
诸葛亮 |刘备->诸葛亮
孙尚香 |刘备->孙尚香
赵云 |刘备->赵云
员工姓名|管理路径
-------|-------------------
刘备 |刘备
关羽 |刘备->关羽
张飞 |刘备->张飞
...
简雍 |刘备->关羽->法正->简雍
孙乾 |刘备->关羽->法正->孙乾
-- Microsoft SQL Server
WITH employee_path (emp_id, emp_name, path) AS
(
SELECT emp_id, emp_name, CAST(emp_name AS VARCHAR) AS path
FROM employee
WHERE manager IS NULL
UNION ALL
SELECT e.emp_id, e.emp_name,
CAST(CONCAT(ep.path, '->', e.emp_name) AS VARCHAR)
FROM employee_path ep
JOIN employee e ON ep.emp_id = e.manager
)
SELECT emp_name AS "员工姓名", PATH AS "管理路径"
FROM employee_path;
-- MySQL、PostgreSQL 以及 SQLite
WITH RECURSIVE t(n) AS
(
SELECT 1
UNION ALL
SELECT n + 1 FROM t
)
SELECT n FROM t;
-- Oracle、Microsoft SQL Server
WITH t(n) AS
(
SELECT 1
UNION ALL
SELECT n + 1 FROM t
)
SELECT n FROM t;
-- MySQL、PostgreSQL 以及 SQLite
WITH RECURSIVE t(n) AS
(
SELECT 1
UNION ALL
SELECT n + 1 FROM t
)
SELECT n FROM t WHERE n < 10;
原文作者:SQL编程思想;如有侵权,请联系管理员删除。