考勤查詢統計SQL指令碼。
阿新 • • 發佈:2018-11-29
本文主要記錄下平時工作中考勤統計中的SQL指令碼,以便於後續翻閱,同時和大家分享一下,不足的地方還請大牛多多給與點評。
1.首先是查詢某員工的考勤記錄。可以根據年份,月份,或者時間段查詢結果,同時也可以去掉人員篩選條件,查詢多個人的考勤結果。以及計算出該員工的打卡是否正常。SQL語句如下所示:
SELECT 員工號,卡號,姓名,日期, '打卡記錄' AS 考勤型別, Substring(日期, 1, 4) AS 年份, Substring(日期, 6, 2) AS 月份, Datename(weekday, 日期) AS 工作日型別, Min(打卡時間) AS 上班打卡時間, Max(打卡時間) AS 下班打卡時間, CASE WHEN Datename(weekday, 日期) <> '星期六' AND Datename(weekday, 日期) <> '星期日' THEN( CASE WHEN Min(打卡時間) = Max(打卡時間) THEN'上班或下班忘打卡' WHEN Min(打卡時間) > '08:00:00' THEN '遲到' WHEN Max(打卡時間) < '17:00:00' THEN '早退' ELSE '正常' END ) ELSE '非工作日打卡' END AS 狀態 FROM (SELECT a.[emp_id] 員工號, a.[card_id] 卡號, b.[emp_fname] 姓名, CONVERT(CHAR(10), sign_time, 120) 日期, CONVERT(VARCHAR, sign_time, 108) 打卡時間, [sign_time] FROM [dbo].[TimeRecords] a LEFT JOIN [dbo].[Employee] b ON a.emp_id = b.emp_id AND a.[card_id] = b.[card_id] WHERE a.emp_id IS NOT NULL AND a.emp_id <> '' AND CONVERT(CHAR(10), sign_time, 120) BETWEEN '2018-09-01' AND '2018-10-30' AND b.[emp_fname] = '姓名') AS mm GROUP BY mm.員工號, 卡號, 姓名, mm.日期 ORDER BY 員工號, 日期 ASC
查詢結構如下所示:
2.根據部門,員工姓名、日期查詢員工的打卡記錄:
SELECT a.emp_fname, b.depart_name, CONVERT(CHAR(10), sign_time, 120) date, Min(c.sign_time) AS BeginTime, Max(c.sign_time) AS EndTime Datediff(minute, Min(c.sign_time), Max(c.sign_time)) AS minute, FROM Employee a LEFT JOIN Departs b ON a.depart_id = b.depart_id LEFT JOIN TimeRecords c ON a.emp_id = c.emp_id WHERE Substring(a.depart_id, 1, 3) = '041' AND CONVERT(CHAR(10), sign_time, 120) BETWEEN '2018-11-01' AND '2018-11-30' AND a.emp_id IS NOT NULL GROUP BY depart_name, emp_fname, CONVERT(CHAR(10), sign_time, 120) ORDER BY depart_name, emp_fname, CONVERT(CHAR(10), sign_time, 120) ASC
查詢結果如下所示:
3.統計某一時間段內的員工的上下班打卡次數,以及遲到或早退30分鐘以內的和30分鐘以上的資料。
SELECT a.emp_fname, b.depart_name, CONVERT(CHAR(10), sign_time, 120) date, Min(c.sign_time) AS BeginTime, Max(c.sign_time) AS EndTime Datediff(minute, Min(c.sign_time), Max(c.sign_time)) AS minute, FROM Employee a LEFT JOIN Departs b ON a.depart_id = b.depart_id LEFT JOIN TimeRecords c ON a.emp_id = c.emp_id WHERE Substring(a.depart_id, 1, 3) = '041' AND CONVERT(CHAR(10), sign_time, 120) BETWEEN '2018-11-01' AND '2018-11-30' AND a.emp_id IS NOT NULL GROUP BY depart_name, emp_fname, CONVERT(CHAR(10), sign_time, 120) ORDER BY depart_name, emp_fname, CONVERT(CHAR(10), sign_time, 120) ASC SELECT b.emp_fname, b.depart_name, Sum(CASE WHEN ms = 0 AND CONVERT(CHAR(10), EndTime, 23) < '12:00:00' THEN 1 ELSE 0 END) AS 上班未打卡, Sum(CASE WHEN ms = 0 AND CONVERT(CHAR(10), EndTime, 23) > '12:00:00' THEN 1 ELSE 0 END) AS 下班未打卡, Sum(CASE WHEN 540 - ms BETWEEN 0 AND 30 THEN 1 ELSE 0 END) AS 遲到或早退30分鐘以內, Sum(CASE WHEN 540 - ms > 30 THEN 1 ELSE 0 END) AS 遲到或早退30分鐘以上 FROM (SELECT TOP 100 PERCENT a.emp_fname, b.depart_name, Min(c.sign_time) AS BeginTime, Max(c.sign_time) AS EndTime, Datediff(minute, Min(c.sign_time), Max(c.sign_time)) AS ms FROM Employee a LEFT JOIN Departs b ON a.depart_id = b.depart_id LEFT JOIN TimeRecords c ON a.emp_id = c.emp_id WHERE Substring(a.depart_id, 1, 3) = '041' AND CONVERT(CHAR(10), sign_time, 120) BETWEEN '2018-11-01' AND '2018-11-30' AND a.emp_id IS NOT NULL GROUP BY depart_name, emp_fname, CONVERT(CHAR(10), sign_time, 120) ORDER BY depart_name, emp_fname, CONVERT(CHAR(10), sign_time, 120) ASC) AS b GROUP BY emp_fname, depart_name ORDER BY depart_name, emp_fname
查詢結果如下:
4.統計各種假期的請假時長 :
/****** Script for SelectTopNRows command from SSMS ******/
SELECT applyUser,
ApplyDept,
Sum(CASE
WHEN leavetype = '事假' THEN leaveHours
ELSE 0
END) AS 事假,
Sum(CASE
WHEN leavetype = '病假' THEN leaveHours
ELSE 0
END) AS 病假,
Sum(CASE
WHEN leavetype = '產檢假' THEN leaveHours
ELSE 0
END) AS 產前病事假,
Sum(CASE
WHEN leavetype = '產假'
OR LeaveType = '陪產假' THEN leaveHours
ELSE 0
END) AS 產假或護理假,
Sum(CASE
WHEN leavetype = '婚假' THEN leaveHours
ELSE 0
END) AS 婚假,
Sum(CASE
WHEN leavetype = '喪假' THEN leaveHours
ELSE 0
END) AS 喪假,
Sum(CASE
WHEN leavetype = '年休假' THEN leaveHours
ELSE 0
END) AS 年假,
Sum(CASE
WHEN leavetype = '公假' THEN leaveHours
ELSE 0
END) AS 公假,
Sum(CASE
WHEN leavetype = '其他' THEN leaveHours
ELSE 0
END) AS 其他,
Sum(CASE
WHEN leavetype = '調休' THEN leaveHours
ELSE 0
END) AS 調休,
Sum(CASE
WHEN leavetype = '工傷假' THEN leaveHours
ELSE 0
END) AS 工傷假
FROM HR_Leave
WHERE CompanyId = 16
AND Node = 2
AND CONVERT(CHAR(10), Start, 120) BETWEEN '2018-09-01' AND '2018-12-30'
GROUP BY ApplyDept,
ApplyUserId,
ApplyUser
SQL執行結果如下所示:
5.根據加班型別,統計各種加班型別的加班時長:
/****** Script for SelectTopNRows command from SSMS ******/
SELECT [ApplyUser],
[ApplyDept],
Sum(CASE
WHEN [OtType] = '平時延長' THEN Duration
ELSE 0
END) AS 平時延長,
Sum(CASE
WHEN [OtType] = '休息日' THEN Duration
ELSE 0
END) AS 休息日,
Sum(CASE
WHEN [OtType] = '法定節假日' THEN Duration
ELSE 0
END) AS 法定節假日
FROM HR_Overtime
WHERE CompanyId = 16
AND Node = 2
AND CONVERT(CHAR(10), CreateDateTime, 120) BETWEEN '2018-09-01' AND '2018-12-30'
GROUP BY [ApplyDept],
ApplyUserId,
[ApplyUser]
查詢結果如下所示:
後續持續更新包含請假、加班、出差等相關聯的綜合查詢。注:請假、出差、加班等流程在其他資料庫中,幾者關聯查詢不太想用DBLink,所以只有單獨查詢出來,在程式碼中用Linq做關聯查詢,關於跨資料庫的關聯查詢,如果哪位老師有好的建議,歡迎留言。謝謝!