You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将SQL打卡表的In/Out时间拆分至不同列创建视图?

实现打卡记录进出时间配对的SQL视图

要实现将打卡记录中的入卡(I)和出卡(O)记录配对,生成包含姓名、入卡时间、出卡时间的视图,且确保出卡时间在入卡时间的0-16小时范围内,可以通过以下两种方式实现:

方法一:基础自连接(适用于单进单出场景)

如果员工每天只有一次入卡和一次出卡记录,直接使用表自连接即可:

CREATE VIEW vw_AttendanceRecords AS
SELECT 
    i.Name,
    i.TimeStamp AS [TimeStamp IN],
    o.TimeStamp AS [Timestamp OUT]
FROM 
    打卡记录表 i
INNER JOIN 
    打卡记录表 o 
    ON i.Name = o.Name
    AND o.TimeStamp >= i.TimeStamp
    AND DATEDIFF(HOUR, i.TimeStamp, o.TimeStamp) BETWEEN 0 AND 16
WHERE 
    i.[In-Out] = 'I'
    AND o.[In-Out] = 'O';

代码说明:

  • 用别名i标记入卡记录,o标记出卡记录,通过Name关联同一名员工的记录
  • 筛选条件限定i的In-Out值为I,o的为O
  • 使用DATEDIFF(HOUR, ...)确保出卡时间在入卡时间的0到16小时范围内,同时通过o.TimeStamp >= i.TimeStamp避免时间顺序颠倒的错误配对

方法二:窗口函数配对(适用于多进多出场景)

如果员工存在同一天多次进出的情况,用窗口函数给每个员工的入、出记录按时间排序,再按序号配对,能更准确地对应顺序的进出:

CREATE VIEW vw_AttendanceRecords AS
WITH InRecords AS (
    SELECT 
        Name,
        TimeStamp AS InTime,
        -- 按员工分组,给入卡记录按时间排序编号
        ROW_NUMBER() OVER (PARTITION BY Name ORDER BY TimeStamp) AS RecordSeq
    FROM 打卡记录表
    WHERE [In-Out] = 'I'
),
OutRecords AS (
    SELECT 
        Name,
        TimeStamp AS OutTime,
        -- 按员工分组,给出卡记录按时间排序编号
        ROW_NUMBER() OVER (PARTITION BY Name ORDER BY TimeStamp) AS RecordSeq
    FROM 打卡记录表
    WHERE [In-Out] = 'O'
)
SELECT 
    ir.Name,
    ir.InTime AS [TimeStamp IN],
    orr.OutTime AS [Timestamp OUT]
FROM InRecords ir
INNER JOIN OutRecords orr 
    ON ir.Name = orr.Name 
    AND ir.RecordSeq = orr.RecordSeq
WHERE DATEDIFF(HOUR, ir.InTime, orr.OutTime) BETWEEN 0 AND 16;

代码说明:

  • 先用CTE分别提取入卡和出卡记录,并用ROW_NUMBER()给每个员工的记录按时间顺序编号
  • 通过员工姓名和记录序号关联对应的入、出记录,保证顺序匹配
  • 最后用DATEDIFF过滤时差在0-16小时内的有效配对

内容的提问来源于stack exchange,提问作者Andy Jansen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 02:00:27