计算每月时间

时间:2018-08-02 06:36:37

标签: sql-server database-design

CREATE TABLE EmpAttendance
(
EmpCode INT,
Time_In Time(5),
Time_Out Time(5),
DayDate date
)

INSERT INTO EmpAttendance VALUES (23, '08:30', '13:00', '2018-07-12');
INSERT INTO EmpAttendance VALUES (23, '13:45', '18:30', '2018-07-12');
INSERT INTO EmpAttendance VALUES (23, '09:15', '12:50', '2018-07-13');
INSERT INTO EmpAttendance VALUES (23, '14:02', '18:22', '2018-07-13');
INSERT INTO EmpAttendance VALUES (23, '08:30', '16:00', '2018-07-14');
INSERT INTO EmpAttendance VALUES (23, '08:45', '17:56', '2018-07-15');
INSERT INTO EmpAttendance VALUES (12, '09:15', '12:50', '2018-07-13');
INSERT INTO EmpAttendance VALUES (12, '14:02', '18:22', '2018-07-13');
INSERT INTO EmpAttendance VALUES (12, '08:30', '16:00', '2018-07-14');

我有这个表结构,用于存储特定日期特定员工的进出时间。我想计算一个员工整个月的总工作时间。

查询应接受2个输入日期参数​​和员工代码,并将输出作为总时数。 我可以每天工作,但是我也想每月计算一次,所以不知道怎么做。

SELECT EmpCode, [DayDate],
FirstIN    = CAST(MIN(Time_In) AS TIME), 
LastOUT    = CAST(MAX(Time_Out) AS TIME), 
HoursSpent = DATEDIFF(HOUR, CAST(MIN(Time_In) AS TIME), CAST(MAX(Time_Out) AS TIME)),
CONVERT(VARCHAR(6), Datediff(second, CAST(MIN(Time_In) AS TIME), CAST(MAX(Time_Out) AS TIME))/3600) 
       + ':' 
       + RIGHT('0' + CONVERT(VARCHAR(2), (Datediff(second, CAST(MIN(Time_In) AS TIME), CAST(MAX(Time_Out) AS TIME)) % 3600) / 60), 2) 
       + ':' 
       + RIGHT('0' + CONVERT(VARCHAR(2), Datediff(second, CAST(MIN(Time_In) AS TIME), CAST(MAX(Time_Out) AS TIME)) % 60) , 2 ) 

       AS hoursSpent
FROM EmpAttendance
GROUP BY EmpCode, DayDate

2 个答案:

答案 0 :(得分:1)

只需将其更改为GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, 0, DayDate), 0)

SELECT  EmpCode, 
    DATEADD(MONTH, DATEDIFF(MONTH, 0, DayDate), 0) as MonthDate,
    --FirstIN    = CAST(MIN(Time_In) AS TIME), 
    --LastOUT    = CAST(MAX(Time_Out) AS TIME), 
    HoursSpent = DATEDIFF(HOUR, CAST(MIN(Time_In) AS TIME), CAST(MAX(Time_Out) AS TIME)),
CONVERT(VARCHAR(6), Datediff(second, CAST(MIN(Time_In) AS TIME), CAST(MAX(Time_Out) AS TIME))/3600) 
       + ':' 
       + RIGHT('0' + CONVERT(VARCHAR(2), (Datediff(second, CAST(MIN(Time_In) AS TIME), CAST(MAX(Time_Out) AS TIME)) % 3600) / 60), 2) 
       + ':' 
       + RIGHT('0' + CONVERT(VARCHAR(2), Datediff(second, CAST(MIN(Time_In) AS TIME), CAST(MAX(Time_Out) AS TIME)) % 60) , 2 ) 

       AS HoursSpent
FROM    EmpAttendance
-- add the condition here in where clause
WHERE   DayDate >= @StartDate
GROUP BY EmpCode, DATEADD(MONTH, DATEDIFF(MONTH, 0, DayDate), 0)

答案 1 :(得分:1)

假设您的Time_InTime_Out总是与同一天相关,则您只需在几分钟内sumdatediff上增加{一天:

declare @t table(EmpCode int
                ,Time_In time(5)
                ,Time_Out time(5)
                ,DayDate date
                );

insert into @t values(23, '08:30', '13:00', '2018-07-12'),(23, '13:45', '18:30', '2018-07-12'),(23, '09:15', '12:50', '2018-07-13'),(23, '14:02', '18:22', '2018-07-13'),(23, '08:30', '16:00', '2018-07-14'),(23, '08:45', '17:56', '2018-07-15'),(12, '09:15', '12:50', '2018-07-13'),(12, '14:02', '18:22', '2018-07-13'),(12, '08:30', '16:00', '2018-07-14');

select EmpCode
        ,dateadd(month,datediff(month,0,DayDate),0) as MonthGroup
        ,sum(datediff(minute,Time_In,Time_Out))/60 as HoursWorked
        ,sum(datediff(minute,Time_In,Time_Out))%60 as MinutesWorked
from @t
group by EmpCode
        ,dateadd(month,datediff(month,0,DayDate),0)
;

输出:

+---------+-------------------------+-------------+---------------+
| EmpCode |       MonthGroup        | HoursWorked | MinutesWorked |
+---------+-------------------------+-------------+---------------+
|      12 | 2018-07-01 00:00:00.000 |          15 |            25 |
|      23 | 2018-07-01 00:00:00.000 |          33 |            51 |
+---------+-------------------------+-------------+---------------+