SQL Server查询需求:基于两表计算时间差生成输出表
解决SQL Server合并两表计算实际时长的问题
没问题,我来帮你搞定这个SQL查询,完全符合你给出的输出规则。咱们先拆解需求,再写代码:
核心思路
- 先处理
Table1的记录:直接计算每条记录Timein和Timeout的分钟差,作为该ID的首行输出; - 再处理
Table2的记录:给每个ID的操作记录按Timein排序,用LEAD()函数获取下一条操作的时间作为当前行的Timeout,如果是最后一条操作,就用对应Table1里的Timeout来收尾,然后计算时长; - 最后把两部分结果合并,按ID排序,确保每个ID的
Table1记录排在最前面。
完整SQL查询语句
WITH Table2WithNextTime AS ( SELECT t2.ID, t2.statusName2 AS statusName, t2.Timein AS TimeIn, -- 获取下一条记录的Timein,没有的话用Table1的Timeout COALESCE(LEAD(t2.Timein) OVER (PARTITION BY t2.ID ORDER BY t2.Timein), t1.Timeout) AS Timeout FROM Table2 t2 JOIN Table1 t1 ON t2.ID = t1.ID ) -- 合并Table1的结果和处理后的Table2结果 SELECT ID, statusName1 AS statusName, Timein AS TimeIn, Timeout, CAST(DATEDIFF(minute, Timein, Timeout) AS VARCHAR(10)) + ':00' AS Actualtime FROM Table1 UNION ALL SELECT ID, statusName, TimeIn, Timeout, CAST(DATEDIFF(minute, TimeIn, Timeout) AS VARCHAR(10)) + ':00' AS Actualtime FROM Table2WithNextTime -- 按ID排序,同时确保Table1的记录在每个ID的最前面 ORDER BY ID, CASE WHEN statusName = statusName1 THEN 0 ELSE 1 END;
代码解释
- CTE
Table2WithNextTime:用LEAD()窗口函数给每个ID的Table2记录匹配下一条操作的时间,最后一条操作则关联Table1的Timeout作为结束时间; UNION ALL:把Table1的原始记录(已计算时长)和处理后的Table2记录合并;- 排序逻辑:先按ID分组,然后通过
CASE语句让Table1的记录排在对应ID的最前面; - 时长计算:用
DATEDIFF(minute, ...)得到分钟数,再拼接:00格式化为你需要的样式。
用你给出的测试数据运行这个查询,就能得到和期望完全一致的输出结果啦。
内容的提问来源于stack exchange,提问作者vinnu
相关产品推荐
相关产品推荐

