Sql中WITH的作用
1. WITH
子句:公共表表达式 (CTE)
WITH
子句是 SQL Server(以及许多现代数据库系统)中支持的功能,用于定义 公共表表达式(CTE)。CTE 是一个临时的结果集,查询在执行过程中可以像表一样引用它。
在你的例子中,WITH
子句定义了一个临时的查询结果,称为 RankedAttendance
。这部分查询将用于后续的主查询。
RankedAttendance
是你给公用表表达式(CTE)取的名字。- 在
WITH
后面的大括号内,可以写一个普通的 SQL 查询,这个查询将返回一个结果集,作为 CTE 的内容。 - 在查询的后续部分,你可以像引用普通表一样引用这个 CTE。
WITH RankedAttendance AS (
-- CTE 查询部分
SELECT PersonID, AttendanceDate, AttendanceStatus,
ROW_NUMBER() OVER (PARTITION BY PersonID ORDER BY AttendanceDate DESC) AS RowNum
FROM a )
2. CTE 的作用
CTE 中的查询为每个 PersonID
(即每个人)根据 AttendanceDate
(考勤日期)降序排序,使用了 ROW_NUMBER()
窗口函数来给每个考勤记录分配一个行号。ROW_NUMBER()
根据 PARTITION BY PersonID
和 ORDER BY AttendanceDate DESC
排序,使得每个人的最新记录会被分配 RowNum = 1
。
-
ROW_NUMBER() OVER (PARTITION BY PersonID ORDER BY AttendanceDate DESC)
:
这个窗口函数会按照PersonID
分组,并对每组按AttendanceDate
降序排列,为每个考勤记录分配一个唯一的行号(从 1 开始)。PARTITION BY PersonID
:表示按PersonID
对数据进行分组,确保每个人的考勤记录被单独排序。ORDER BY AttendanceDate DESC
:对每个人的考勤记录按日期降序排列,确保最新的考勤记录排在最前面。
3. 主查询:从 CTE 中提取最新记录
SELECT PersonID, AttendanceDate,
AttendanceStatus FROM RankedAttendance WHERE RowNum = 1;
在主查询中,我们从 CTE(RankedAttendance
)中选择 PersonID
、AttendanceDate
和 AttendanceStatus
,并且使用 WHERE RowNum = 1
来过滤出每个人的最新一条考勤记录,因为每个人的最新记录的 RowNum
为 1。
总结:WITH
子句的作用
WITH
子句 定义了一个 公共表表达式(CTE),这个 CTE 临时存储了每个人的考勤记录,并为每条记录分配了一个按日期降序排列的行号。- 主查询从这个 CTE 中获取了每个人的最新考勤记录,即
RowNum = 1
的记录。
为什么使用 CTE?
-
提高可读性:CTE 提供了一种清晰的方式来分解复杂的查询,使得整个查询的结构更加易于理解。通过先定义 CTE,主查询变得更加简洁。
-
简化多次引用:CTE 允许你在查询中多次引用相同的结果集,而不需要重复编写相同的子查询。
-
递归查询:CTE 也可以用于递归查询,这对于处理层级结构(如组织结构、目录树等)非常有用。