1. FROM:第一步肯定要先识别出查询中涉及的所有表。

  2. JOIN:根据 FROM 子句中的表,执行 JOIN 操作。如果有多个 JOIN,数据库会根据内部算法和统计信息确定 JOIN 的顺序,以尝试优化查询效率。

  3. WHERE:对 JOIN 操作的结果应用 WHERE 中的过滤条件。这一步会排除不符合条件的行。

  4. GROUP BY:如果查询包含 GROUP BY 子句,此时对数据进行分组。分组操作通常在 WHERE 条件过滤之后进行。

  5. HAVING:如果有 HAVING 子句,它会在 GROUP BY 之后应用。HAVING 子句用于筛选分组后的数据集。

  6. SELECT:选择特定的列。实际上,所需列的数据可能在执行过程的早期就已经被获取,但在此阶段会根据 SELECT 子句确定最终输出的列。

  7. DISTINCT:如果指定了 DISTINCT 关键字,此时会去除重复的行。

  8. ORDER BY:如果查询指定了 ORDER BY,现在将对结果进行排序。注意,如果使用了 GROUP BY,MySQL 可能会利用这个排序作为 GROUP BY 的一部分。

  9. LIMIT:最后,应用 LIMIT 子句来限制返回的行数。这通常是整个查询过程的最后一步。

举个例子:

SELECT name, COUNT(*)
FROM employees
JOIN departments ON employees.department_id = departments.id
WHERE employees.salary > 50000
GROUP BY departments.name
HAVING COUNT(*) > 10
ORDER BY name
LIMIT 5;

如上面的SQL,我们是找出平均薪水超过 50,000 的部门中员工人数超过 10 人的前 5 个部门,他的执行过程如下:

  1. FROM:确定涉及的表:employeesdepartments

  2. JOIN:根据 employees.department_id = departments.id 条件执行 JOIN 操作,将两个表的数据合并。

  3. WHERE:应用 WHERE 过滤条件 employees.salary > 50000,只保留薪水超过 50,000 的员工记录。

  4. GROUP BY:根据 departments.name 对结果集进行分组。

  5. HAVING:应用 HAVING 条件 COUNT(*) > 10,筛选出员工人数超过 10 人的部门。

  6. SELECT:选择要显示的列:name(部门名称)和 COUNT(*)(员工数量)。

  7. DISTINCT:此查询没有使用 DISTINCT 关键字,所以跳过。

  8. ORDER BY:根据 name(部门名称)对结果集进行排序。

  9. LIMIT:应用 LIMIT,只返回前 5 条记录。