MySQL - 公共表表达式:初学者指南

你好,未来的数据库大师们!今天,我们将踏上一段令人兴奋的旅程,探索MySQL中的公共表表达式(CTEs)。如果你是编程新手,不用担心——我会成为你的友好向导,我们会一步一步地进行。在本教程结束时,你将能够像专业人士一样编写CTEs!

MySQL - Common Table Expressions

公共表表达式是什么?

在我们深入之前,让我们从基础开始。想象你正在组织一个大型派对(因为谁不喜欢一个好的数据库派对,对吧?)。你可能会制作一个嘉宾名单、一个食物名单和一个活动名单。这些名单帮助你组织思绪,使规划变得更容易。公共表表达式就像是这些名单,但用于你的数据库查询!

公共表表达式,简称CTE,是一个临时的命名结果集,你可以在SELECT、INSERT、UPDATE、DELETE或MERGE语句中引用它。它就像创建了一个只存在于查询期间的临时表。酷吧?

MySQL中的WITH子句:你的CTE魔法棒

在MySQL中,我们使用WITH子句来创建CTE。就像说,“嘿,MySQL,我想创建一个临时结果集,我要称它为X。”让我们来看一个简单的例子:

WITH cte_name AS (
SELECT column1, column2
FROM table_name
WHERE condition
)
SELECT * FROM cte_name;

让我们分解一下:

  1. WITH告诉MySQL我们将定义一个CTE。
  2. cte_name是我们给CTE的名字(你可以选择你喜欢的任何名字)。
  3. AS后面跟着定义我们的CTE中将有哪种数据的查询。
  4. 在CTE定义之后,我们有我们的主查询,它使用CTE。

现在,让我们尝试一个现实世界的例子。想象我们有一个学生和他们的成绩的表:

CREATE TABLE students (
id INT PRIMARY KEY,
name VARCHAR(50),
grade INT
);

INSERT INTO students VALUES
(1, 'Alice', 85),
(2, 'Bob', 92),
(3, 'Charlie', 78),
(4, 'Diana', 95),
(5, 'Eva', 88);

WITH high_achievers AS (
SELECT name, grade
FROM students
WHERE grade > 90
)
SELECT * FROM high_achievers;

在这个例子中,我们创建了一个名为high_achievers的CTE,它只包括成绩超过90的学生。然后,我们从这个CTE中选择了所有列。结果将显示Bob和Diana,我们的佼佼者!

从多个表中的CTEs:加入派对

CTEs不仅限于一个表。哦不,它们可以像你需要的那么复杂!让我们向我们的学校数据库中添加一个课程表:

CREATE TABLE courses (
id INT PRIMARY KEY,
name VARCHAR(50),
teacher VARCHAR(50)
);

INSERT INTO courses VALUES
(1, 'Math', 'Mr. Smith'),
(2, 'Science', 'Ms. Johnson'),
(3, 'History', 'Mrs. Brown');

CREATE TABLE enrollments (
student_id INT,
course_id INT,
FOREIGN KEY (student_id) REFERENCES students(id),
FOREIGN KEY (course_id) REFERENCES courses(id)
);

INSERT INTO enrollments VALUES
(1, 1), (1, 2), (2, 2), (3, 3), (4, 1), (4, 3), (5, 2);

WITH student_courses AS (
SELECT s.name AS student_name, c.name AS course_name
FROM students s
JOIN enrollments e ON s.id = e.student_id
JOIN courses c ON e.course_id = c.id
),
science_students AS (
SELECT student_name
FROM student_courses
WHERE course_name = 'Science'
)
SELECT * FROM science_students;

哇,那可真不少!让我们分解一下:

  1. 我们创建了两个新表:coursesenrollments
  2. 我们定义了一个名为student_courses的CTE,它连接这些表来获取学生和他们的课程列表。
  3. 我们定义了另一个名为science_students的CTE,它使用第一个CTE来找到学习科学的学生。
  4. 最后,我们选择了所有的科学学生。

这个查询将向我们展示Alice、Bob和Eva——我们的未来科学家!

CTE的力量:你为什么应该关心?

你可能会想,“为什么要这么麻烦?我不能只用子查询吗?”好问题!CTEs提供了几个优点:

  1. 可读性:CTEs使复杂的查询更容易阅读和理解。就像把一个大问题分解成更小、更易于管理的部分。

  2. 可重用性:你可以在主查询中多次引用一个CTE,这比重复子查询更高效。

  3. 递归:CTEs可以是递归的,允许你轻松处理层次结构或树状结构的数据(但这个话题留到另一天再讲)。

CTE方法:你的查询工具瑞士军刀

让我们总结一下你可以使用CTEs的不同方式:

方法 描述 示例
基础CTE 定义一个简单的命名结果集 WITH cte AS (SELECT * FROM table)
多个CTEs 在一个查询中定义多个CTEs WITH cte1 AS (...), cte2 AS (...)
嵌套CTEs 在另一个CTE中引用一个CTE WITH outer_cte AS (WITH inner_cte AS (...) SELECT * FROM inner_cte)
递归CTEs 创建一个引用自身的CTE WITH RECURSIVE cte AS (...)

请记住,像任何强大的工具一样,明智地使用CTEs。它们非常适合组织复杂查询,但对于简单操作,一个直接的SELECT可能就足够了。

结论:你的CTE之旅开始了!

恭喜你!你已经迈出了进入公共表表达式世界的第一步。我们已经涵盖了基础知识,看到了如何使用WITH子句,甚至处理了多表CTEs。记住,熟能生巧,所以不要害怕在你的数据库中进行实验。

在你继续MySQL旅程时,你会发现CTEs是你查询工具箱中的宝贵工具。它们将帮助你写出更干净、更高效、更易于维护的代码。谁知道呢?也许有一天,你会成为教别人关于CTE魔法的人!

继续编码,保持好奇心,愿你的查询总是返回你期望的结果!下次见,快乐的数据处理!

Credits: Image by storyset