SQL查询以获取员工缺席的日期

时间:2017-01-26 04:42:58

标签: sql sql-server database-design

我有一张存储员工交易的表格。身份证刷入并刷出。 列:员工ID,员工姓名,刷卡日期和时间,刷出日期和时间。

我需要一个有效的MS SQL Server查询来获取员工ID以及他们缺席的日期。

(注意:可以创建附加表格以回答问题。)

2 个答案:

答案 0 :(得分:7)

正如其他人所说,有一个表存储所有工作日会有所帮助。为简单起见,我们将其命名为business_calendar,并将所有工作日日期存储在名为DATETIME的{​​{1}}列中。由于我不知道您使用的SQL Server版本,我将始终使用working_day - 所以那些仅代表日期的人将没有时间参与。 This answer有助于在进行比较时咨询如何删除时间部分。

为安全起见,建议只查询没有员工刷入或关闭记录的日期 - 这可能适用于边缘情况,例如员工在午夜之后工作或者可能存在DATETIME如果由于某种原因,其中一个刷卡或滑出没有注册。

要查找员工缺席的日期:

NULL

...或者要获取所有员工的列表以及他们缺席的日期,可以使用DECLARE @emp_id INT; SET @emp_id = 1; SELECT @emp_id AS employee_id, bc.working_day AS absent_day FROM business_calendar bc WHERE NOT EXISTS ( SELECT * FROM attendance a WHERE a.employee_id = @emp_id AND (DATEADD(day, DATEDIFF(day, 0, a.swipe_in), 0) = bc.working_day OR DATEADD(day, DATEDIFF(day, 0, a.swipe_out), 0) = bc.working_day));

CROSS JOIN

当然可以通过SELECT e.id AS employee_id, bc.working_day AS absent_day FROM business_calendar bc CROSS JOIN employee e WHERE NOT EXISTS ( SELECT * FROM attendance a WHERE a.employee_id = e.id AND (DATEADD(day, DATEDIFF(day, 0, a.swipe_in), 0) = bc.working_day OR DATEADD(day, DATEDIFF(day, 0, a.swipe_out), 0) = bc.working_day)); 进一步AND条件轻松过滤到仅包含员工子集和/或日期。

在这里演示:http://rextester.com/VPTTM33285

答案 1 :(得分:0)

根据我所做的假设(只有swipe_in,忽略swipe_out),这应该有效。还假设日期范围是一个月的日期范围。我使用了this生成表格的示例。

DECLARE @StartDate DATETIME 
SET @StartDate = DATEADD(Month,-1,GetDate())
Declare @EndDate DATETIME
SET @EndDate = Getdate()

SELECT * From (
SELECT * FROM EmployeeAttendance EA
RIGHT OUTER JOIN (
SELECT  DATEADD(DAY, nbr - 1, @StartDate) as CalenderDate
FROM    ( SELECT    ROW_NUMBER() OVER ( ORDER BY c.object_id ) AS Nbr
          FROM      sys.columns c
        ) nbrs
WHERE   nbr - 1 <= DATEDIFF(DAY, @StartDate, @EndDate)
) A1 ON (Dateadd(dd,0,Datediff(dd,0,A1.CalenderDate)) = DateAdd(dd,0,Datediff(dd,0,EA.SwipeIn))))A2
WHERE Name IS NULL