SQL Server 函数实战:一条 SQL 替代 3000 行代码的计算逻辑(第一课)

在企业级应用开发过程中,面对复杂的业务统计需求,通常需要编写大量代码来处理数据。前面几篇文章讲述了在Oracle中如何高效利用SQL语句,而在 SQL Server 中,借助CASE WHEN(类似于 Oracle 的DECODE)函数与分组函数的巧妙配合,我们也能够仅用一条 SQL 语句,实现原本需要 3000 行代码才能完成的复杂计算逻辑。本文将围绕企业组织架构中的部门级请假数据统计场景展开,详细介绍SQLserver的具体实现方法。

一、基础准备:构建业务数据表

1. 创建单位部门表(模拟组织架构)


CREATE TABLE t_dept (

dept_id INT PRIMARY KEY, -- 部门ID(主键)

dept_name VARCHAR(50) NOT NULL, -- 部门名称

parent_dept_id INT, -- 上级部门ID(根部门为0)

create_time DATETIME DEFAULT GETDATE() -- 创建时间

);

-- 插入示例数据(三级部门架构)

INSERT INTO t_dept (dept_id, dept_name, parent_dept_id) VALUES (1, '集团总部', 0);

INSERT INTO t_dept (dept_id, dept_name, parent_dept_id) VALUES (2, '技术研发部', 1);

INSERT INTO t_dept (dept_id, dept_name, parent_dept_id) VALUES (3, '产品运营部', 1);

INSERT INTO t_dept (dept_id, dept_name, parent_dept_id) VALUES (4, '后端开发组', 2);

INSERT INTO t_dept (dept_id, dept_name, parent_dept_id) VALUES (5, '前端开发组', 2);

2. 创建人员请假信息表

CREATE TABLE t_leave (

user_id VARCHAR(20) PRIMARY KEY, -- 人员账号(主键)

user_name VARCHAR(30) NOT NULL, -- 人员姓名

dept_id INT NOT NULL, -- 所属部门ID

leave_days DECIMAL(5,1), -- 请假天数(保留1位小数)

leave_type VARCHAR(20), -- 请假类型(年假/事假/病假等)

leave_status VARCHAR(10), -- 请假状态('完成'/'进行中')

apply_time DATETIME DEFAULT GETDATE() -- 申请时间

);

-- 插入模拟数据(覆盖不同部门/类型/状态)

INSERT INTO t_leave VALUES

('U001', '张三', 4, 3.5, '年假', '完成', '2025-06-01'),

('U002', '李四', 5, 2.0, '事假', '进行中', '2025-06-10'),

('U003', '王五', 3, 1.5, '病假', '完成', '2025-06-15'),

('U004', '赵六', 4, 5.0, '年假', '进行中', '2025-06-20'),

('U005', '周七', 2, 1.0, '事假', '完成', '2025-06-05'),

('U006', '吴八', 3, 3.0, '年假', '进行中', '2025-06-25');

二、CASE WHEN 函数基础用法:实现简单条件转换

1. 基础语法解析


CASE expression

WHEN search1 THEN result1

WHEN search2 THEN result2

...

ELSE default

END

CASE WHEN函数类似于 Oracle 的DECODE函数,也类似于编程语言中的switch-case结构,按照顺序匹配条件。它不仅支持数值型和字符型数据比较,还能处理更复杂的逻辑判断,最后一个ELSE子句为默认值(可选) 。

2. 示例:状态码转换


-- 将状态编码转为中文描述

SELECT

user_name,

leave_type,

CASE leave_status

WHEN '完成' THEN '已完成'

WHEN '进行中' THEN '处理中'

ELSE '未知状态'

END AS status_desc

FROM t_leave;

-- 输出结果:

-- 张三 年假 已完成

-- 李四 事假 处理中

-- 王五 病假 已完成

三、CASE WHEN 进阶用法:多条件分支处理

1. 复杂业务场景:多维度分类统计

需求:统计不同请假类型的占比(按部门维度)

SELECT

dept_id,

SUM(CASE leave_type WHEN '年假' THEN leave_days ELSE 0 END) AS annual_leave_days,

SUM(CASE leave_type WHEN '事假' THEN leave_days ELSE 0 END) AS personal_leave_days,

SUM(CASE leave_type WHEN '病假' THEN leave_days ELSE 0 END) AS sick_leave_days

FROM t_leave

GROUP BY dept_id;

-- 关键逻辑:

-- 针对每个部门,按请假类型累加对应天数

-- 非目标类型自动返回0,避免NULL影响SUM计算

2. 优势体现

CASE WHEN相较于 Oracle 的DECODE函数,支持更灵活的条件判断,不仅可以进行等值比较,还能处理范围判断(如WHEN leave_days > 3 THEN ...),在复杂业务逻辑处理中更具优势。

四、终极实战:单 SQL 实现三级统计需求

业务目标

从根部门(集团总部,dept_id=1)开始,统计每个子部门的:

        1.每种请假类型的总天数

        2.完成状态的请假单数

        3.进行中状态的请假单数

核心 SQL 语句


WITH dept_hierarchy AS (

-- 递归查询获取所有子部门(包含自身)

SELECT dept_id, dept_name, parent_dept_id

FROM t_dept

WHERE dept_id = 1 -- 根部门ID

UNION ALL

SELECT d.dept_id, d.dept_name, d.parent_dept_id

FROM t_dept d

JOIN dept_hierarchy dh ON d.parent_dept_id = dh.dept_id

)

SELECT

dh.dept_name AS 部门名称,

-- 请假类型统计(年假/事假/病假,其他类型自动归为0)

SUM(CASE tl.leave_type WHEN '年假' THEN tl.leave_days ELSE 0 END) AS 年假总天数,

SUM(CASE tl.leave_type WHEN '事假' THEN tl.leave_days ELSE 0 END) AS 事假总天数,

SUM(CASE tl.leave_type WHEN '病假' THEN tl.leave_days ELSE 0 END) AS 病假总天数,

-- 状态统计

SUM(CASE tl.leave_status WHEN '完成' THEN 1 ELSE 0 END) AS 完成请假数,

SUM(CASE tl.leave_status WHEN '进行中' THEN 1 ELSE 0 END) AS 进行中请假数

FROM dept_hierarchy dh

LEFT JOIN t_leave tl ON dh.dept_id = tl.dept_id

GROUP BY dh.dept_id, dh.dept_name

ORDER BY dh.dept_id;

执行结果示例

部门名称

年假总天数

事假总天数

病假总天数

完成请假数

进行中请假数

集团总部

0.0

0.0

0.0

0

0

技术研发部

4.5

1.0

0.0

1

1

产品运营部

1.5

0.0

3.0

1

1

后端开发组

3.5

0.0

0.0

1

1

前端开发组

0.0

2.0

0.0

0

1

关键技术点解析

  1. 递归 CTE(公用表表达式):构建部门层级关系,实现从根部门到所有子部门的遍历,与 Oracle 的递归查询逻辑相似,但语法更简洁直观。
  2. CASE WHEN 与 SUM 结合:横向扩展统计维度(类型 / 状态)和自动处理 NULL 值(非匹配项返回 0)
  3. LEFT JOIN 优化:确保无数据部门也能显示(如集团总部本身无请假记录)

五、总结:SQL 编程的降维打击

通过CASE WHEN函数与分组函数的组合,在 SQL Server 中我们同样实现了:

1、代码量锐减:原本需要 Java/Python 编写的多层循环 + 条件判断,浓缩为单条 SQL

2、性能提升:数据库层直接完成复杂计算,减少数据传输开销

3、维护便利:业务逻辑集中在 SQL 层,无需修改应用代码即可调整统计规则

在 SQL Server 的开发过程中,合理运用CASE WHEN和递归 CTE 等特性,能够极大提升开发效率。后续文章中,我们还将进一步探索更复杂的统计逻辑实现,如果你对当前内容有任何疑问,或想补充特定需求,欢迎随时交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI、少年郎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值