SQL的高级功能能够帮助开发者处理复杂的数据分析、批量操作和逻辑封装需求,相比基础查询语句,这些功能更适合应对企业级业务场景中的复杂数据处理任务。本文结合实际案例介绍常用SQL高级功能的使用方法。
一、窗口函数
窗口函数可以在不改变原有行数的情况下,对数据进行分组内的排序、聚合计算,常用于排名、同比环比计算等场景。窗口函数的基本语法为函数名() OVER (PARTITION BY 分组列 ORDER BY 排序列),其中PARTITION BY用于指定分组逻辑,ORDER BY用于指定分组内的排序规则。
以下是一个查询每个部门员工薪资排名的示例:
-- 查询每个部门内员工的薪资排名
SELECT
dept_id,
emp_id,
salary,
-- 按部门分组,组内按薪资降序排名,相同薪资排名相同,后续排名跳过重复位次
RANK() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS salary_rank
FROM
employee;
常用的窗口函数分为聚合类窗口函数和排序类窗口函数,聚合类如SUM()、AVG()等,排序类如RANK()、ROW_NUMBER()、DENSE_RANK()等,使用时需要根据业务需求选择合适的函数。
二、公用表表达式(CTE)
公用表表达式也就是CTE,通过WITH关键字定义临时结果集,能够简化复杂查询的逻辑,提升SQL语句的可读性,也支持递归查询处理层级数据。CTE的作用范围仅限当前查询语句,不会持久化存储。
以下是使用CTE查询薪资高于部门平均薪资的员工示例:
-- 先通过CTE计算每个部门的平均薪资
WITH dept_avg_salary AS (
SELECT
dept_id,
AVG(salary) AS avg_salary
FROM
employee
GROUP BY
dept_id
)
-- 关联员工表和CTE结果,筛选薪资高于部门平均的员工
SELECT
e.dept_id,
e.emp_id,
e.salary,
d.avg_salary
FROM
employee e
JOIN
dept_avg_salary d ON e.dept_id = d.dept_id
WHERE
e.salary > d.avg_salary;
递归CTE常用于处理组织架构、分类目录等层级数据,通过WITH RECURSIVE关键字定义,包含锚定部分和递归部分,能够遍历完整的层级关系。
三、存储过程
存储过程是预先编译并存储在数据库中的一组SQL语句集合,支持参数传递、逻辑判断和循环操作,适合封装重复执行的复杂业务逻辑,减少应用层和数据库的交互次数。
以下是一个封装新增员工并更新部门人数的存储过程示例:
-- 创建存储过程,参数为员工姓名、部门ID、薪资
CREATE PROCEDURE add_employee(
IN p_emp_name VARCHAR(50),
IN p_dept_id INT,
IN p_salary DECIMAL(10,2)
)
BEGIN
-- 开启事务保证操作原子性
START TRANSACTION;
-- 插入员工记录
INSERT INTO employee (emp_name, dept_id, salary)
VALUES (p_emp_name, p_dept_id, p_salary);
-- 更新对应部门的人数统计
UPDATE department
SET emp_count = emp_count + 1
WHERE dept_id = p_dept_id;
-- 提交事务
COMMIT;
END;
存储过程创建后可以通过CALL语句调用,传入对应参数即可执行封装的逻辑,不同数据库的存储过程语法略有差异,使用时需要参考对应数据库的官方文档。
四、事务控制
事务是数据库操作的基本单位,一组操作要么全部成功要么全部失败,能够保证数据的一致性。事务的核心特性是ACID,即原子性、一致性、隔离性、持久性。SQL中通过START TRANSACTION开启事务,COMMIT提交事务,ROLLBACK回滚事务。
以下是一个转账场景的事务示例:
-- 开启事务 START TRANSACTION; -- 从账户A扣除1000元 UPDATE account SET balance = balance - 1000 WHERE account_id = 1; -- 向账户B增加1000元 UPDATE account SET balance = balance + 1000 WHERE account_id = 2; -- 检查两个操作是否都执行成功,这里简化为直接提交 -- 如果出现异常则执行ROLLBACK回滚所有操作 COMMIT;
在实际业务中,事务的隔离级别会影响并发场景下的数据读取结果,常用的隔离级别有读未提交、读已提交、可重复读、串行化,需要根据业务对数据一致性的要求选择合适的隔离级别。
五、实战场景总结
在实际的数据处理工作中,这些高级功能通常会组合使用。比如在做月度销售报表时,可以用CTE先清洗过滤原始销售数据,再用窗口函数计算每个区域的销售排名和环比增长率,最后将结果存储到报表表中,整个过程可以用存储过程封装,通过事务保证数据操作的完整性。
掌握这些SQL高级功能能够减少应用层的代码逻辑,把复杂的数据处理放到数据库层执行,充分利用数据库的计算能力,提升整体系统的运行效率。