SQL递归查询必要前提是数据库支持WITH RECURSIVE(如PostgreSQL、SQL Server等),且初始与递归成员列名类型严格一致,MySQL 5.7及更早版本不支持。
什么是 SQL 递归查询的必要前提
不是所有数据库都支持递归查询,WITH RECURSIVE 是标准写法,但只在 PostgreSQL、SQL Server、SQLite 3.8.3+、Oracle(用 START WITH ... CONNECT BY)、MySQL 8.0+ 中可用。MySQL 5.7 或更早版本直接不支持,强行写会报错 ERROR 1064。PostgreSQL 要求初始查询(anchor member)和递归查询(recursive member)的列名、类型严格一致,否则报 UNION types text and integer cannot be matched。
确认你的环境支持前,先运行一句测试:
WITH RECURSIVE t(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM t WHERE n < 3) SELECT * FROM t;
能返回 1/2/3 就说明递归可用。
构造员工上下级关系表的关键字段
递归依赖明确的自关联结构,必须有:employee_id、manager_id(可为 NULL 表示顶层领导),以及要对比的 salary。别用 parent_id 或 boss_id 这类模糊命名,容易在 JOIN 或递归中漏判 NULL。
常见错误是把 manager_id 设为 NOT NULL,导致 CEO 数据无法进入初始查询;或者把 manager_id 类型设成 INT 而实际存了字符串(比如 ‘NULL’ 文本),导致递归断链。
建表示例(PostgreSQL):
CREATE TABLE employees ( employee_id INT PRIMARY KEY, name TEXT, manager_id INT, salary NUMERIC(10,2) );
写递归 CTE 计算每人的直属上级与薪资差
核心是两段拼接:初始查询选所有无上级(manager_id IS NULL)或需作为起点的人;递归段用 JOIN 回原表,匹配 manager_id = e.employee_id,从而逐层向下展开。