1. 程式人生 > >考勤查詢統計SQL指令碼。

考勤查詢統計SQL指令碼。

本文主要記錄下平時工作中考勤統計中的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做關聯查詢,關於跨資料庫的關聯查詢,如果哪位老師有好的建議,歡迎留言。謝謝!