給定打卡記錄表(empId, starttime, endtime, isaddwork),上班 9:00、下班 17:00,需統計 11 月各員工遲到、早退次數。關鍵在於時間提取與條件聚合。
SELECT
empId AS `員工ID`,
SUM(CASE WHEN TIME(starttime) > '09:00:00' THEN 1 ELSE 0 END) AS `遲到次數`,
SUM(CASE WHEN TIME(endtime) < '17:00:00' AND isaddwork = 0 THEN 1 ELSE 0 END) AS `早退次數`
FROM `打卡表`
WHERE DATE(starttime) BETWEEN '2014-11-01' AND '2014-11-30'
GROUP BY empId;
TIME() 函數直接提取時間部分,比 DATE_FORMAT 更高效清晰。isaddwork=1),否則加班晚走會被誤判。WHERE 先過濾月份,減少聚合掃描行數。DATE_FORMAT(starttime, '%Y-%m') 到 GROUP BY。若在 Java 中執行,建議使用 PreparedStatement 綁定月份參數,避免 SQL 注入;結果集映射到 Map<Integer, AttendanceStat> 供上層業務使用。