计算每天MS SQL的出勤和标记缺席者

时间:2015-05-30 11:18:03

标签: sql-server sql-server-2008 time-and-attendance

这是考勤记录表:

CREATE TABLE [dbo].[DeviceLogs] (
    [DeviceLogId]  INT            NOT NULL,
    [UserId]       NVARCHAR (50)  NOT NULL,
    [LogDate]      DATETIME       NOT NULL,
);

这是我的员工表:

CREATE TABLE [dbo].[Employees] (
    [EmployeeId]             INT            IDENTITY (1, 1) NOT NULL,
    [EmployeeName]           NVARCHAR (50)  NULL,
    [UserId]           NVARCHAR (50)  NOT NULL,
    [Gender]                 NVARCHAR (255) NULL,
    [DepartmentId]           NVARCHAR (255) NULL,
    [Designation]            NVARCHAR (255) NULL,
    [CategoryId]             INT            NULL,
    [DOJ]                    DATETIME       NULL,
    [DOR]                    DATETIME       NULL,
    [Status]                 NVARCHAR (255) NULL,
    [DOB]                    DATETIME       NULL,
);

我们会在第一张表中插入考勤记录。

现在我想计算每一天每个员工的出勤率。

SELECT [userid]                                           AS identit, 
       CONVERT(VARCHAR, userid), 
       Min(logdate)                                       AS lowtime, 
       Max(logdate)                                       AS hightime, 
       CONVERT(VARCHAR, Max(logdate) - Min(logdate), 108) AS dur, 
       CASE 
         WHEN CONVERT(VARCHAR, Max(logdate) - Min(logdate), 108) IS NOT NULL 
       THEN 
         'present' 
         ELSE 'Absent' 
       END                                                AS Status 
FROM   [dbo].[devicelogs] 
GROUP  BY [userid] 
ORDER  BY userid DESC 

这是我正在使用的MS SQl查询。 但是只有当这个人有出勤记录时才会给我结果。

即使在缺席的情况下,我也想计算出勤率。 我想让它每天重复一次。

请在这里帮助我。

3 个答案:

答案 0 :(得分:1)

如果没有错,则应该有一个User表,其中包含所有用户的列表

您必须Left/Right outer join User表与devicelogs表。

像这样。

SELECT U.[userid]                                         AS identit, 
       CONVERT(VARCHAR, U.userid), 
       Min(logdate)                                       AS lowtime, 
       Max(logdate)                                       AS hightime, 
       CONVERT(VARCHAR, Max(logdate) - Min(logdate), 108) AS dur, 
       CASE 
         WHEN d.userid IS NOT NULL THEN 'present' 
         ELSE 'Absent' 
       END                                                AS Status 
FROM   [users] U -- Replace with the table that contains all the users
       LEFT OUTER JOIN [dbo].[devicelogs] D 
                    ON U.userid = D.userid 
GROUP  BY [userid] 
ORDER  BY U.userid DESC 

答案 1 :(得分:0)

要获取每日报告/列表,通常最好有一个日期表,其中包含您需要的所有可能日期,例如1.1.2000 - 31.12.2099。使用它,您可以轻松创建按该日期分组的查询,如下所示:

SELECT 
    e.userid,
    d.[date],
    l.first,
    l.last,
    case when l.first is null then 'Absent' else 'Present' end as status
FROM   
    [dbo].[Employees] e
    cross join [dbo].[Dates] d
    outer apply (
        select min(logdate) as first, max(logdate) as last
        from [dbo].[devicelogs] l
        where l.userid = e.userid and
        l.logdate >= d.[date] and l.logdate < dateadd(day, 1, d.[date]
    ) l
where d.[date] >= '20150501' and d.[date] < getdate()
GROUP BY e.userid, d.[date] 
ORDER BY e.userid desc, d.[date] desc

你当然也可以用devicelog来做,但是如果有一个没有任何日志的日期你会完全错过。

没试过这个,希望没有错误:)

答案 2 :(得分:0)

首先,您必须澄清为什么日志表可能有一些没有日志日期的用户,因为logdate设置为NOT NULL并且您正在查询日志表并期望得到一些没有logdate的用户。

算法是:当员工不在日志表中时将其设置为不存在并将持续时间等于0。其他人计算持续时间并将他设置为现在。加上他的日志日志和日志的最后日期。

1)获取一个显示空日期

用户的表格
 select E.UserID as UserID,L.LogDate as logdate from  employee E
 full outer join
 DeviceLogs L
 on E.UserID=L.UserID    

2)将您的代码应用于此表