常见数据库关键字示例 SQL 及执行顺序分析(带详细注释)
示例 SQL 及执行顺序分析(带详细注释)
示例 1:基础查询(含多表关联、过滤、分组、排序)
SELECT -- 1. 选择字段(包含聚合函数和别名)e.department, COUNT(e.employee_id) AS total_employees, -- 聚合函数AVG(e.salary) AS avg_salary, MAX(e.salary) AS max_salary
FROM employees e
JOIN departments d ON e.department_id = d.department_id -- 2. 表关联(JOIN)
WHERE e.hire_date >= '2020-01-01' -- 3. 行级过滤(WHERE)
GROUP BY e.department -- 4. 分组(GROUP BY)
HAVING AVG(e.salary) > 5000 -- 5. 分组后过滤(HAVING)
ORDER BY avg_salary DESC -- 6. 排序(ORDER BY)
LIMIT 10; -- 7. 限制结果(LIMIT)
示例 2:窗口函数与子查询
SELECT -- 1. 选择字段(包含窗口函数)e.*, SUM(e.salary) OVER (PARTITION BY department) AS dept_total_salary, -- 窗口函数(SUM OVER)RANK() OVER (ORDER BY salary DESC) AS salary_rank -- 排名函数(RANK OVER)
FROM (-- 子查询(先执行)SELECT * FROM employees WHERE age BETWEEN 25 AND 35 -- 子查询过滤
) e
WHERE e.department = 'Tech' -- 2. 外层过滤(WHERE)
ORDER BY salary_rank -- 3. 排序(ORDER BY)
LIMIT 5; -- 4. 限制结果(LIMIT)
示例 3:多表关联 + UNION + DISTINCT
SELECT -- 第一个 SELECT 分支o.order_id, c.customer_name, o.total_amount, COUNT(DISTINCT oi.product_id) AS products_count
FROM orders o
JOIN customers c ON o.customer_id = c.customer_id
LEFT JOIN order_items oi ON o.order_id = oi.order_id
WHERE o.order_date BETWEEN '2023-01-01' AND '2023-12-31' -- 过滤订单日期
GROUP BY o.order_id, c.customer_name, o.total_amount
HAVING products_count > 2 -- 分组后过滤
UNION -- 合并结果集
SELECT -- 第二个 SELECT 分支(不同结构)'Summary' AS order_id, 'Total Customers' AS customer_name, COUNT(DISTINCT c.customer_id) AS total_customers, NULL AS products_count
FROM customers c
WHERE c.registration_date >= '2023-01-01'
ORDER BY total_amount DESC -- 全局排序
LIMIT 5; -- 限制最终结果
执行顺序与逻辑关系
SQL 执行流程(通用顺序)
- FROM/JON:处理表关联(如
JOIN
)和子查询。 - WHERE:过滤行级条件。
- GROUP BY:按字段分组。
- HAVING:过滤分组后的结果。
- WINDOW FUNCTION:计算窗口函数(依赖分组后的数据)。
- SELECT:选择字段并计算表达式(如聚合函数、别名)。
- DISTINCT:去重(若存在)。
- ORDER BY:排序结果。
- LIMIT/OFFSET:限制返回行数。
关键子句间的逻辑关系
子句 | 依赖关系 | 输出结果 |
---|---|---|
FROM | 无 | 基础表或子查询的原始数据 |
WHERE | 依赖 FROM 的结果 | 过滤后的行数据 |
GROUP BY | 依赖 WHERE 的结果 | 按字段分组后的数据集 |
HAVING | 依赖 GROUP BY 的结果 | 过滤分组后的组 |
WINDOW FUNCTION | 依赖 GROUP BY 和 HAVING 的结果(若存在) | 添加窗口函数计算的列 |
SELECT | 依赖所有前置子句的结果 | 最终输出的字段(含聚合函数、别名、窗口函数结果) |
ORDER BY | 依赖 SELECT 的结果 | 排序后的结果集 |
LIMIT/OFFSET | 依赖 ORDER BY 的结果(若存在) | 最终返回的有限行数 |
表格总结:各 SQL 的关键字段与执行顺序
SQL 示例 | 关键子句 | 执行顺序 | 注释要点 |
---|---|---|---|
示例 1 | SELECT , FROM , JOIN , WHERE , GROUP BY , HAVING , ORDER BY , LIMIT | 1. JOIN → 2. WHERE → 3. GROUP BY → 4. HAVING → 5. SELECT → 6. ORDER BY → 7. LIMIT | - JOIN 先于 WHERE 执行- GROUP BY 必须包含非聚合字段 department - HAVING 过滤分组后的平均工资 |
示例 2 | SELECT (窗口函数), FROM (子查询), WHERE , ORDER BY , LIMIT | 1. 子查询 → 2. WHERE → 3. 窗口函数 → 4. SELECT → 5. ORDER BY → 6. LIMIT | - 子查询先执行过滤年龄 - 窗口函数依赖分组后的数据(隐式分组) - RANK() 为全局排名 |
示例 3 | SELECT , FROM (多表 JOIN), WHERE , GROUP BY , HAVING , UNION , ORDER BY , LIMIT | 1. JOIN → 2. WHERE → 3. GROUP BY → 4. HAVING → 5. UNION → 6. SELECT → 7. ORDER BY → 8. LIMIT | - UNION 合并两个不同结构的 SELECT 结果- DISTINCT 去重产品 ID- 最终排序全局生效 |
关键点说明
-
窗口函数的特殊性:
- 示例 2 中的
SUM(...) OVER (PARTITION BY ...)
在GROUP BY
之后执行,允许对分组后的数据进行计算,但不会合并行。 - 窗口函数可与非聚合字段(如
e.*
)同时出现在SELECT
中。
- 示例 2 中的
-
子查询的优先级:
- 示例 2 的内层子查询(
SELECT * FROM employees WHERE age BETWEEN 25 AND 35
)在外部查询的FROM
阶段优先执行。
- 示例 2 的内层子查询(
-
DISTINCT
的位置:- 示例 3 中的
COUNT(DISTINCT product_id)
在GROUP BY
阶段计算,确保统计唯一产品数量。
- 示例 3 中的
-
UNION
的处理:- 示例 3 的
UNION
合并两个 SELECT 结果后,才会执行全局的ORDER BY
和LIMIT
。
- 示例 3 的
通过以上分析,可清晰理解 SQL 各子句的执行顺序及相互依赖关系,帮助优化查询性能和结果准确性。