基于SQL的用户时间表

时间:2014-07-28 16:39:46

标签: sql sql-server sql-server-2008

我有一张桌子,我一直在收集用户的时钟,闹钟时间,这显示在日历上没问题。但是,现在我想看看所有用户的工作时间。

每次用户进入时,都会创建一条新记录。每次用户退出时,也会创建一条新记录。

下面的我的SQL代码允许我调出时钟输入和时钟输出时间:

DECLARE @StartDate DateTime;
DECLARE @EndDate DateTime;
DECLARE @AssumedShiftStartTime DateTime;
DECLARE @AssumedShiftEndTime DateTime;
DECLARE @EmployeeName nvarchar(200);
DECLARE @ShiftStart DateTime
DECLARE @ShiftEnd DateTime


-- Date format: YYYY-MM-DD
SET @StartDate = '2014-07-01 00:00:00'
SET @EndDate = DATEADD (DAY, 1, @StartDate);  -- Add one day
SET @AssumedShiftEndTime = '18:00:00'
SET @AssumedShiftStartTime = '09:00:00'
SET @EmployeeName = 'Paul';

--------------  Get Clock IN / OUT TIMES -----------------
SELECT EmployeeAttendance.LastUpdate, EmployeeAttendance.ClockInTime, EmployeeAttendance.ClockOutTime
FROM            EmployeeAttendance INNER JOIN
                         Membership ON EmployeeAttendance.UserId = Membership.UserId

WHERE EmployeeAttendance.LastUpdate >= @StartDate AND EmployeeAttendance.LastUpdate <= @EndDate
AND Membership.Username = @EmployeeName 

其中给出了以下结果:

    LastUpdate                 ClockInTime                 ClockOutTime
    2014-07-01 08:48:08.650    2014-07-01 08:48:08.650     NULL    
    2014-07-01 18:04:39.943    NULL                        2014-07-01 18:04:39.923
    2014-07-02 08:48:08.680    2014-07-01 09:00:08.340     NULL    
    2014-07-02 18:04:39.343    NULL                        2014-07-01 18:00:39.623
    2014-07-03 08:48:08.620    2014-07-01 08:58:08.860     NULL    
    2014-07-03 18:04:39.455    NULL                        2014-07-01 18:05:39.985

我真正想要实现的是返回以下结果的东西。

编辑:如果结果返回null,我想使用@AssumedShiftStartTime或@AssumedShiftEndTime来允许结果总计小时计算但很难,因为有两个单独的记录记录为时钟输入和时钟输出:

DATE          CLOCK-IN-TIME    CLOCK-OUT-TIME   TOTAL-HOURS
2014-07-01    08:49            18:04            9 Hours 15 Mins
2014-07-02    09:00            18:00            9 Hours 00 Mins
2014-07-03    08:58            18:05            9 Hours 07 Mins


Total-This-Month
27 Hours 15 Mins

编辑:感谢您Sean Lange的帮助。在应用你的回复的帮助后,我得到以下输出,其中显示了两行代表Clock In和Clock Out。我试图确定如何获得一天结果的最佳方法,计算总小时数,合并下两个并计算小时数等等。我认为这比它需要的更复杂,也许是SQL逻辑的时间重新编码

2014-07-01 08:48:08.650 NULL    NULL    NULL
NULL    2014-07-01 18:04:39.923 NULL    NULL
2014-07-02 08:54:03.483 NULL    NULL    NULL
NULL    2014-07-02 17:09:34.940 NULL    NULL
2014-07-03 08:48:01.070 NULL    NULL    NULL
NULL    2014-07-03 18:12:11.487 NULL    NULL
2014-07-04 08:48:07.983 NULL    NULL    NULL
NULL    2014-07-04 18:07:09.390 NULL    NULL
2014-07-05 08:56:24.410 NULL    NULL    NULL
NULL    2014-07-05 14:19:12.800 NULL    NULL
2014-07-08 08:44:56.727 NULL    NULL    NULL
NULL    2014-07-08 18:15:12.143 NULL    NULL
2014-07-09 08:46:15.103 NULL    NULL    NULL
NULL    2014-07-09 17:10:46.327 NULL    NULL
2014-07-10 08:57:14.733 NULL    NULL    NULL
NULL    2014-07-10 18:10:37.897 NULL    NULL
2014-07-11 08:52:10.783 NULL    NULL    NULL
NULL    2014-07-11 18:08:58.580 NULL    NULL
2014-07-12 08:56:20.073 NULL    NULL    NULL
NULL    2014-07-12 14:15:44.103 NULL    NULL
2014-07-15 08:47:04.330 NULL    NULL    NULL
NULL    2014-07-15 18:10:05.800 NULL    NULL
2014-07-16 08:56:34.490 NULL    NULL    NULL
NULL    2014-07-16 17:05:06.627 NULL    NULL
2014-07-17 08:46:37.263 NULL    NULL    NULL
NULL    2014-07-17 18:06:08.840 NULL    NULL
2014-07-18 08:52:56.200 NULL    NULL    NULL
NULL    2014-07-18 18:11:25.750 NULL    NULL
2014-07-19 08:54:36.277 NULL    NULL    NULL
NULL    2014-07-19 14:15:09.620 NULL    NULL
2014-07-22 08:56:30.623 NULL    NULL    NULL
NULL    2014-07-22 16:03:00.653 NULL    NULL
2014-07-23 08:49:53.687 NULL    NULL    NULL
NULL    2014-07-23 17:07:37.943 NULL    NULL
2014-07-24 08:52:08.690 NULL    NULL    NULL
2014-07-25 08:57:13.477 NULL    NULL    NULL
NULL    2014-07-25 18:09:01.793 NULL    NULL
2014-07-26 08:53:42.597 NULL    NULL    NULL
NULL    2014-07-26 14:03:21.063 NULL    NULL

任何帮助都将被感激地接受。

谢谢

2 个答案:

答案 0 :(得分:1)

这样的帮助吗?

declare @Times table(ClockIn datetime, ClockOut datetime)

insert @Times
select '2014-07-01 08:49', '2014-07-01 18:04' union all
select '2014-07-01 09:00', '2014-07-01 18:00'

select *
    , datediff(hour, ClockIn, ClockOut) - case when datediff(minute, ClockIn, ClockOut) % 60 > 0 then 1 else 0 end as MyHours
    ,datediff(minute, ClockIn, ClockOut) % 60 as MyMinutes
from @Times

答案 1 :(得分:1)

这里我们编写一些测试数据:

DECLARE @TimeSheet TABLE
(
    EmpId INT,
    LastUpdate DATETIME,
    ClockInTime DATETIME,
    ClockOutTime DATETIME
)

INSERT INTO @TimeSheet
VALUES
(201, '2014-07-01 08:48:08.650',    '2014-07-01 08:48:08.650'   ,NULL                     ),    
(201, '2014-07-01 18:04:39.943',    NULL                        ,'2014-07-01 18:04:39.923'),
(201, '2014-07-02 08:48:08.680',    '2014-07-01 09:00:08.340'   ,NULL                     ),
(201, '2014-07-02 18:04:39.343',    NULL                        ,'2014-07-01 18:00:39.623'),
(201, '2014-07-03 08:48:08.620',    '2014-07-01 08:58:08.860'   ,NULL                     ),
(201, '2014-07-03 18:04:39.455',    NULL                        ,'2014-07-01 18:05:39.985'),
(110, '2014-07-01 08:48:08.650',    '2014-07-01 06:48:08.650'   ,NULL                     ),    
(110, '2014-07-01 18:04:39.943',    NULL                        ,'2014-07-01 14:01:39.923'),
(110, '2014-07-02 08:48:08.680',    '2014-07-01 07:10:08.340'   ,NULL                     ),
(110, '2014-07-02 18:04:39.343',    NULL                        ,'2014-07-01 14:00:39.623'),
(110, '2014-07-03 08:48:08.620',    '2014-07-01 06:58:58.860'   ,NULL                     ),
(110, '2014-07-03 18:04:39.455',    NULL                        ,'2014-07-01 14:01:39.985');

现在让我们创建一个CTE来对我们的数据进行编号:

WITH TimeRows AS
(
    SELECT *,
        ROW_NUMBER() OVER (PARTITION BY EmpId, CAST(LastUpdate AS DATE) ORDER BY LastUpdate) RN
    FROM @TimeSheet
)

现在我们查询CTE以查找我们的clockin和clockout时间:

SELECT T1.EmpId,
    T1.ClockInTime,
    T2.ClockOutTime,
    DATEDIFF(HOUR, T1.ClockInTime, T2.ClockOutTime) AS DHour,
    DATEDIFF(MINUTE, T1.ClockInTime, T2.ClockOutTime) % 60 AS DMinutes
FROM TimeRows T1
INNER JOIN TimeRows T2
    ON T2.EmpId = T1.EmpId
    AND T2.RN = T1.RN + 1
    AND CAST(T2.LastUpdate AS DATE) = CAST(T1.LastUpdate AS DATE)

这是输出:

EmpId   ClockInTime ClockOutTime    DHour   DMinutes
110 2014-07-01 06:48:08.650 2014-07-01 14:01:39.923 8   13
110 2014-07-01 07:10:08.340 2014-07-01 14:00:39.623 7   50
110 2014-07-01 06:58:58.860 2014-07-01 14:01:39.987 8   3
201 2014-07-01 08:48:08.650 2014-07-01 18:04:39.923 10  16
201 2014-07-01 09:00:08.340 2014-07-01 18:00:39.623 9   0
201 2014-07-01 08:58:08.860 2014-07-01 18:05:39.987 10  7