⚡ 编程实验室🏗️ HTML🎨 CSS⚡ JavaScript🐍 Python🗄️ SQL☕ Java⚛️ React💚 Vue🟢 Node.js⚙️ C语言🐘 PHP🐹 Go🔷 TypeScript🐬 MySQL🔧 C++🎯 C#🦀 Rust🅱️ Bootstrap💡 jQuery🎸 Django🍃 MongoDB👗 Sass🎪 Kotlin📊 R语言📋 XML📊 Excel🐘 PostgreSQL🐳 Docker🅰️ Angular🎮 游戏🏠 网站首页

SQL CTE 公用表表达式

学习WITH · 难度:高级 · +15XP

SQL CTE 公用表表达式

CTE(Common Table Expression,公用表表达式)是一种在 SQL 查询中定义临时命名结果集的方式。它使用 WITH 关键字开头,可以理解为给一个子查询起了一个名字,让你在后续的主查询中多次引用它。CTE 最大的优势是让复杂查询变得清晰易读——你可以将一个大问题拆解为多个有名称的步骤,像搭积木一样逐层构建查询逻辑。

CTE 基本语法

WITH cte名称 AS (
    -- 子查询
    SELECT 列1, 列2 FROM 表名 WHERE 条件
)
SELECT * FROM cte名称;

CTE 的作用范围仅限于紧随其后的一条语句(SELECT/INSERT/UPDATE/DELETE),执行完毕后即被销毁。

基础示例

-- 计算平均分,然后查询高于平均分的学生
WITH avg_scores AS (
    SELECT AVG(score) AS avg_score FROM students
)
SELECT name, score
FROM students, avg_scores
WHERE score > avg_score;

-- 等价于子查询写法(对比可读性) SELECT name, score FROM students WHERE score > (SELECT AVG(score) FROM students);

多个CTE链式定义

你可以在一个查询中定义多个 CTE,后面的 CTE 可以引用前面的 CTE:

WITH
-- 第一步:计算每个学生的平均分
student_avg AS (
    SELECT student_id, AVG(score) AS avg_score
    FROM scores GROUP BY student_id
),
-- 第二步:基于上一步筛选优等生
top_students AS (
    SELECT student_id, avg_score
    FROM student_avg WHERE avg_score >= 85
)
-- 第三步:关联学生信息
SELECT s.name, t.avg_score
FROM top_students t
JOIN students s ON s.id = t.student_id;

CTE + 窗口函数

CTE 与窗口函数配合使用是常见的高效查询模式:

WITH ranked AS (
    SELECT name, score,
           ROW_NUMBER() OVER (ORDER BY score DESC) AS rank
    FROM students
)
SELECT name, score, rank FROM ranked WHERE rank <= 3;

CTE vs 子查询 vs 临时表

特性CTE子查询临时表
可读性高(有名称)低(嵌套)
可复用同一查询内可多次引用需重复编写跨查询可用
存储不存储(虚拟)不存储物理存储
递归支持支持不支持不支持

实战任务

  1. 使用 CTE 计算平均分,查询高于平均分的学生
  2. 定义两个 CTE 链式查询:先算平均分,再筛选高分
  3. 结合 CTE 和 ROW_NUMBER 查询前 3 名
Ctrl+Enter
🚀 升级VIP
解锁全部课程+AI助手

🏆 学习排行

加载中...

📊 统计

📖 146 篇
0 完成
🔥 0