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

优化考勤表:删除员工每日冗余打卡记录的SQL问题

解决absen表每日员工打卡记录优化问题

问题根源

你当前的查询仅按IDkaryawan分组,计算的是该员工所有打卡记录中的全局最早/最晚时间,而非按日期拆分的每日极值,这就是批量员工数据时出错的核心原因。

核心修正思路

必须按员工ID + 打卡日期双重分组,确保每个员工的每日打卡记录独立计算上下班时间。


方案1:简洁聚合查询(仅需核心上下班时间)

如果只需要员工ID、日期、Clock In和Clock Out这几个核心字段,直接用聚合函数+日期分组即可:

MySQL / PostgreSQL

SELECT
  IDkaryawan,
  DATE(jam) AS tanggal,
  MIN(jam) AS clock_in,
  MAX(jam) AS clock_out
FROM absen
GROUP BY IDkaryawan, DATE(jam)
ORDER BY IDkaryawan, tanggal;

SQL Server

SELECT
  IDkaryawan,
  CAST(jam AS DATE) AS tanggal,
  MIN(jam) AS clock_in,
  MAX(jam) AS clock_out
FROM absen
GROUP BY IDkaryawan, CAST(jam AS DATE)
ORDER BY IDkaryawan, tanggal;

方案2:保留完整打卡记录(需原表全部字段)

如果需要保留打卡记录的其他字段(比如打卡设备、状态标记等),可以用窗口函数筛选每日的最早/最晚记录:

MySQL 8.0+ / PostgreSQL / SQL Server

WITH ranked_records AS (
  SELECT
    *,
    -- 标记每日最早打卡(Clock In)
    ROW_NUMBER() OVER (
      PARTITION BY IDkaryawan, DATE(jam) 
      ORDER BY jam ASC
    ) AS rn_clock_in,
    -- 标记每日最晚打卡(Clock Out)
    ROW_NUMBER() OVER (
      PARTITION BY IDkaryawan, DATE(jam) 
      ORDER BY jam DESC
    ) AS rn_clock_out
  FROM absen
)
SELECT
  IDkaryawan,
  DATE(jam) AS tanggal,
  jam AS record_time,
  CASE rn_clock_in WHEN 1 THEN 'Clock In' ELSE 'Clock Out' END AS record_type
  -- 此处可添加原表其他需要保留的字段
FROM ranked_records
WHERE rn_clock_in = 1 OR rn_clock_out = 1
ORDER BY IDkaryawan, tanggal, record_time;

效果验证

比如某员工2024-05-20有3次打卡:2024-05-20 08:00:00、2024-05-20 12:30:00、2024-05-20 18:00:00,上述查询会返回:

  • 方案1:一行记录,clock_in=08:00:00,clock_out=18:00:00
  • 方案2:两行记录,分别对应08:00的Clock In和18:00的Clock Out

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 10:09:50