2026-10-22 09:11:53
SQL中WITH子句(公用表表达式CTE)的用法WITH子句用于创建临时命名的结果集(公用表表达式,CTE),可在同一查询中多次引用,从而提升代码的可读性、重用性和性能。
核心功能创建临时表
通过WITH <临时表名> AS (<子查询>)定义临时结果集,仅在当前查询中有效,查询结束后自动销毁。
示例:WITH TempTable AS (SELECT * FROM Employees WHERE department = 'IT')SELECT * FROM TempTable;
支持多CTE定义
可同时定义多个CTE,用逗号分隔,后续CTE可引用前面的CTE。
示例:WITH CTE1 AS (SELECT id, name FROM Users),CTE2 AS (SELECT id, AVG(score) AS avg_score FROM CTE1 GROUP BY id)SELECT * FROM CTE2;
递归查询
通过WITH RECURSIVE实现递归逻辑(如层级数据遍历)。
示例(计算1到10的累加):WITH RECURSIVE Numbers AS ( SELECT 1 AS n UNION ALL SELECT n + 1 FROM Numbers WHERE n < 10)SELECT SUM(n) FROM Numbers;
代码可重用性避免重复编写相同子查询,例如在复杂分析中多次引用同一中间结果。
性能优化数据库可能对CTE进行优化(如物化),减少重复计算,尤其对复杂子查询效果显著。
可读性提升将长查询拆分为逻辑块,例如:
WITH HighValueCustomers AS ( SELECT customer_id FROM Orders WHERE total > 1000),RecentOrders AS ( SELECT * FROM Orders WHERE order_date > '2023-01-01')SELECT * FROM RecentOrders WHERE customer_id IN (SELECT customer_id FROM HighValueCustomers);作用域限制CTE仅在定义它的查询中有效,无法跨查询使用。
数据库兼容性
主流数据库(如PostgreSQL、SQL Server、Oracle)均支持标准WITH语法。
MySQL 8.0+、SQLite 3.8.3+支持CTE,旧版本需改用临时表或子查询。
递归CTE的终止条件递归CTE必须包含终止条件,否则可能导致无限循环。
分析员工薪资与部门平均薪资的差异:
WITH DeptAvgSalaries AS ( SELECT department, AVG(salary) AS avg_salary FROM Employees GROUP BY department),EmployeeStats AS ( SELECT e.name, e.salary, d.department, das.avg_salary FROM Employees e JOIN DeptAvgSalaries das ON e.department = das.department JOIN Departments d ON e.department_id = d.id)SELECT name, salary, department, avg_salary, salary - avg_salary AS diff_from_avgFROM EmployeeStatsWHERE salary > avg_salary;总结WITH子句通过临时结果集简化复杂查询,尤其适合多步骤分析、递归逻辑或重复使用的子查询。合理使用CTE能显著提升SQL代码的清晰度和执行效率。