mysql-sql查询结构和执行顺序

发布于:2025-04-11 ⋅ 阅读:(45) ⋅ 点赞:(0)

在 MySQL 中,SQL 查询的执行顺序是非常重要的。


标准 SQL 查询结构

一个典型的 SQL 查询可能包含以下部分:

SELECT [DISTINCT] column1, aggregate_function(column2), ...
FROM table_name
[JOIN other_table ON join_conditions]
[WHERE where_conditions]
[GROUP BY column1, column2, ...]
[HAVING group_conditions]
[ORDER BY column1 [ASC|DESC], column2 [ASC|DESC], ...]
[LIMIT row_count OFFSET offset];

SQL 查询的实际执行顺序

尽管我们书写 SQL 查询时按照上述顺序排列,但 MySQL 实际上会以以下顺序执行这些部分:

1. FROM 和 JOIN
  • 作用:确定查询的数据来源(表),并应用 JOIN 操作将多个表组合在一起。
  • 执行内容
    • 读取指定的表。
    • 如果有 JOIN,则根据连接条件合并表中的数据。
  • 示例
    FROM orders
    JOIN customers ON orders.customer_id = customers.id
    
2. WHERE
  • 作用:对从 FROMJOIN 得到的结果集进行初步过滤。
  • 执行内容
    • 只保留满足 WHERE 条件的行。
    • 注意:此时不能使用聚合函数,因为分组尚未发生。
  • 示例
    WHERE orders.status = 'completed'
    
3. GROUP BY
  • 作用:将结果集按指定的列或表达式进行分组。
  • 执行内容
    • 将数据划分为多个组,每组具有相同的 GROUP BY 列值。
    • 此时可以开始计算聚合函数(如 COUNT(), SUM() 等)。
  • 示例
    GROUP BY customers.country
    
4. 聚合函数计算
  • 作用:对每个分组应用聚合函数。
  • 执行内容
    • 计算每个分组的聚合值,例如 COUNT(*), SUM(order_amount) 等。
  • 示例
    SELECT customers.country, COUNT(orders.order_id) AS order_count
    
5. HAVING
  • 作用:对分组后的结果进行进一步过滤。
  • 执行内容
    • 过滤掉不满足 HAVING 条件的分组。
    • 注意:HAVING 是唯一可以使用聚合函数的过滤条件(不同于 WHERE)。
  • 示例
    HAVING COUNT(orders.order_id) > 10
    
6. SELECT
  • 作用:选择最终要返回的列或表达式。
  • 执行内容
    • 根据 SELECT 子句中指定的列或表达式返回结果。
    • 如果使用了 DISTINCT,则在此步骤去除重复的行。
  • 示例
    SELECT customers.country, COUNT(orders.order_id) AS order_count
    
7. ORDER BY
  • 作用:对最终结果集进行排序。
  • 执行内容
    • 根据指定的列或表达式对结果进行升序(ASC)或降序(DESC)排序。
  • 示例
    ORDER BY order_count DESC
    
8. LIMIT / OFFSET
  • 作用:限制返回的行数。
  • 执行内容
    • LIMIT 用于限制返回的最大行数。
    • OFFSET 用于跳过指定数量的行。
  • 示例
    LIMIT 10 OFFSET 0
    

完整示例

假设有一个订单系统,包含以下两个表:

  • orders: 存储订单信息。

    • order_id: 订单 ID
    • customer_id: 客户 ID
    • status: 订单状态(如 “completed”, “pending”)
    • amount: 订单金额
  • customers: 存储客户信息。

    • customer_id: 客户 ID
    • country: 客户所在国家

我们需要统计每个国家的已完成订单数量,并仅显示订单数量大于 5 的国家,最后按订单数量降序排列。

SQL 查询
SELECT 
    customers.country,
    COUNT(orders.order_id) AS completed_order_count
FROM 
    customers
JOIN 
    orders ON customers.customer_id = orders.customer_id
WHERE 
    orders.status = 'completed'
GROUP BY 
    customers.country
HAVING 
    COUNT(orders.order_id) > 5
ORDER BY 
    completed_order_count DESC
LIMIT 10;
执行顺序分析
  1. FROM 和 JOIN

    • customers 表和 orders 表中读取数据,并通过 JOIN 合并它们。
  2. WHERE

    • 过滤出 orders.status = 'completed' 的记录。
  3. GROUP BY

    • customers.country 对数据进行分组。
  4. 聚合函数计算

    • 计算每个国家的订单数量 COUNT(orders.order_id)
  5. HAVING

    • 过滤掉订单数量小于等于 5 的国家。
  6. SELECT

    • 返回 customers.countrycompleted_order_count
  7. ORDER BY

    • completed_order_count 降序排列。
  8. LIMIT

    • 最多返回 10 条记录。

总结

  1. 聚合函数的作用

    • 聚合函数只能在 SELECTHAVINGORDER BY 子句中使用。
    • WHERE 子句中不能直接使用聚合函数,因为此时分组尚未完成。
  2. 执行顺序的关键点

    • 数据先通过 FROMJOIN 获取。
    • 然后通过 WHERE 进行初步过滤。
    • 接着通过 GROUP BY 分组并计算聚合值。
    • 使用 HAVING 对分组结果进行过滤。
    • 最后通过 SELECTORDER BYLIMIT 输出最终结果。

理解 SQL 查询的执行顺序对于优化查询性能以及解决复杂查询问题非常重要!如果还有其他疑问,请随时告诉我!


网站公告

今日签到

点亮在社区的每一天
去签到