我有一张桌子,用于存储员工身份证刷卡和刷卡的交易.列:员工ID,员工姓名,刷卡日期和时间,刷出日期和时间.
我需要一个有效的MS SQL Server查询来获取员工ID和他们缺席的日期.
(注意:可以创建附加表格以回答问题.)
正如其他人所说,有一个存储所有工作日的表将会有所帮助.为简单起见,假设将其命名business_calendar
并将所有工作日日期存储在DATETIME
名为的列中working_day
.因为我不知道你正在使用哪个版本的SQL Server DATETIME
,所以我将在整个过程中使用s - 所以那些只代表日期的SQL 将没有时间.这个答案对于比较时如何删除时间部分很有用.
为了安全起见,建议只查询没有员工刷入或关闭记录的日期 - 这可能适用于边缘情况,例如员工在午夜之后工作或者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
通过进一步的WHERE
条件轻松过滤到仅包括员工的子集和/或日期.
在这里演示:http://rextester.com/VPTTM33285