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

如何对比行数不同的表中日期列解决SSRS报表打卡匹配问题

解决方案

实现层优先选择

优先在查询层实现该逻辑,SSRS报表层仅做展示和简单样式渲染即可。原因是多对多打卡记录的匹配需要做去重、排序、状态标记,查询层(SQL层面)的集合运算性能远高于报表层的表达式/自定义代码,逻辑也更易维护。

核心问题根源

你当前的关联逻辑是简单的人员+日期+时间差条件关联,两个系统的多条打卡记录会生成笛卡尔积,已经匹配过的记录没有被标记为「已使用」,才会出现重复匹配、误判异常的问题。

具体调整方案

1. 给两侧打卡记录加匹配序号

首先对两个表的打卡记录按人员、打卡日期、打卡类型分组后,按时间升序排序打序号,保证同个人员同一天的第N次上班/下班打卡一一对应:

  • 处理Table1:
SELECT 
    badge,
    clockIn,
    clockOut,
    CAST(clockIn AS DATE) AS clockDate,
    -- 按人员、日期分组,给上班打卡排序打序号
    ROW_NUMBER() OVER(PARTITION BY badge, CAST(clockIn AS DATE) ORDER BY clockIn ASC) AS rn_in,
    ROW_NUMBER() OVER(PARTITION BY badge, CAST(clockIn AS DATE) ORDER BY clockOut ASC) AS rn_out
FROM Table1
  • 处理Table2:先拆分上下班打卡子集,分别打序号
-- 上班打卡子集
SELECT 
    Badge AS badge,
    clockTime AS clockIn_t2,
    CAST(clockTime AS DATE) AS clockDate,
    ROW_NUMBER() OVER(PARTITION BY Badge, CAST(clockTime AS DATE) ORDER BY clockTime ASC) AS rn_in
FROM Table2 WHERE Reason = 'In'

-- 下班打卡子集
SELECT 
    Badge AS badge,
    clockTime AS clockOut_t2,
    CAST(clockTime AS DATE) AS clockDate,
    ROW_NUMBER() OVER(PARTITION BY Badge, CAST(clockTime AS DATE) ORDER BY clockTime ASC) AS rn_out
FROM Table2 WHERE Reason = 'Out'

2. 调整关联逻辑

关联时除了人员、日期、时间差条件,额外加上序号匹配,避免同一条记录被多次匹配:

SELECT 
    t1.badge,
    t1.clockIn,
    t1.clockOut,
    t2_in.clockIn_t2,
    t2_out.clockOut_t2,
    -- 异常标记:匹配不到就是异常
    CASE 
        WHEN t2_in.clockIn_t2 IS NULL OR ABS(DATEDIFF(MINUTE, t1.clockIn, t2_in.clockIn_t2)) > 60 THEN '上班打卡异常'
        WHEN t2_out.clockOut_t2 IS NULL OR ABS(DATEDIFF(MINUTE, t1.clockOut, t2_out.clockOut_t2)) > 60 THEN '下班打卡异常'
        ELSE '正常'
    END AS exception_flag
FROM 处理后的Table1 t1
LEFT JOIN 处理后的Table2上班子集 t2_in 
    ON t1.badge = t2_in.badge 
    AND t1.clockDate = t2_in.clockDate 
    AND t1.rn_in = t2_in.rn_in
    AND ABS(DATEDIFF(MINUTE, t1.clockIn, t2_in.clockIn_t2)) <= 60
LEFT JOIN 处理后的Table2下班子集 t2_out
    ON t1.badge = t2_out.badge 
    AND t1.clockDate = t2_out.clockDate 
    AND t1.rn_out = t2_out.rn_out
    AND ABS(DATEDIFF(MINUTE, t1.clockOut, t2_out.clockOut_t2)) <= 60

按这个逻辑,你样例中12345的第二条Table2上班打卡(12:41)只会匹配Table1中同序号的第二次上班打卡,不会匹配到第一条Table1的记录,不会出现重复行和误判。

3. 特殊场景兜底(可选)

如果存在跨班次的打卡异常情况(比如某个人漏打一次,后面的打卡序号错位),可以在上述匹配后,再单独把未匹配的记录拿出来做二次模糊匹配,标记为「待核实」即可,避免正常匹配的结果被干扰。

报表层补充说明

如果你的权限仅能修改SSRS报表无法修改查询逻辑,也可以用报表的LookupSet函数+自定义代码实现已匹配记录的标记,但数据量超过1000行就会出现明显卡顿,仅适合小数据量场景使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 02:39:04