0

这是考勤记录表:

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 查询。但只有当这个人有出勤日志时,它才会给我结果。

即使人不在,我也想计算出勤率。我希望它每天都重复。

请在这里帮助我。

4

3 回答 3

1

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

你必须Left/Right outer joinUserdevicelogs同桌。

像这样的东西。

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 
于 2015-05-30T11:43:50.717 回答
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 来做到这一点,但如果有一个日期没有任何日志,您将完全错过它。

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

于 2015-05-30T12:42:09.283 回答
0

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

算法是:当员工不在日志表中时,将他设置为缺席,并将持续时间设为 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)将您的代码应用于此表

于 2015-05-30T14:13:07.373 回答