计算其他列的数据

时间:2014-02-05 19:37:33

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

我写了这个查询,以显示特定日期(如果他来了)员工的总工作时间和加班时间。我想如果对于特定日期,人的INtime和OutTime是空的,那么将00:00放入他的intime,outtime,totalworkingtime,overtime,例如它是星期天所以很明显没有InTime和OutTime然后它应该在时间列中显示00:00。注意:仅在提及人InTIme时输入日期,否则不输入DateVisited。

e.g。

EmplID  EmplName ShiftID intime Outtime totalworking overtime  dateVisited
0000001 John     S001    00:00  00:00   00:00:       00:00     2013-12-01

查询:

WITH    times
          AS ( SELECT t1.EmplID
                   ,t3.EmplName
                   ,MIN(t1.RecTime) AS InTime
                   ,MAX(t2.RecTime) AS [TimeOut]
                   ,t4.ShiftId AS ShiftID
                   ,t4.StAtdTime AS ShStartTime
                   ,t4.EndAtdTime AS ShEndTime
                   ,CAST(MIN(t1.RecTime) AS DATETIME) AS InTimeSub
                   ,CAST(MAX(t2.RecTime) AS DATETIME) AS TimeOutSub
                   ,t1.RecDate AS [DateVisited]
                FROM AtdRecord t1
                INNER JOIN AtdRecord t2
                    ON t1.EmplID = t2.EmplID
                       AND t1.RecDate = t2.RecDate
                       AND t1.RecTime < t2.RecTime
                INNER JOIN HrEmployee t3
                    ON t3.EmplID = t1.EmplID
                INNER JOIN AtdShiftSect t4
                    ON t3.ShiftId = t4.ShiftId
                GROUP BY t1.EmplID
                   ,t3.EmplName
                   ,t1.RecDate
                   ,t4.ShiftId
                   ,t4.StAtdTime
                   ,t4.EndAtdTime)
    SELECT EmplID
           ,EmplName
           ,ShiftId AS ShiftID
           ,InTime
           ,[TimeOut]
           ,CONVERT(CHAR(5), CAST([TimeOutSub] - InTimeSub AS TIME), 108) TotalWorkingTime
           ,[DateVisited]
           ,CASE WHEN [InTime] IS NOT NULL
                      AND [TimeOut] IS NOT NULL
                 THEN CONVERT(CHAR(5), CASE WHEN CAST([TimeOutSub] AS DATETIME) >= ShEndTime
                                                 AND ShiftID = 'S002'
                                            THEN LEFT(CONVERT(VARCHAR(12), DATEADD(ms,
                                                                                   DATEDIFF(ms,
                                                                                            CAST(ShEndTime AS DATETIME),
                                                                                            CAST([TimeOutSub] AS DATETIME)),
                                                                                   0), 108), 5)
                                            WHEN CAST([TimeOutSub] AS DATETIME) >= ShEndTime
                                                 AND ShiftID = 'S001'
                                            THEN LEFT(CONVERT(VARCHAR(12), DATEADD(ms,
                                                                                   DATEDIFF(ms,
                                                                                            CAST(ShEndTime AS DATETIME),
                                                                                            CAST([TimeOutSub] AS DATETIME)),
                                                                                   0), 108), 5)
                                            ELSE '00:00'
                                       END, 108)
                 ELSE 'ABSENT'
            END AS OverTime
        FROM times
        ORDER BY EmplID
           ,ShiftID
           ,DateVisited

2 个答案:

答案 0 :(得分:0)

对于您的情况,最好的方法是创建一个表格,为您提供分数计算的分钟数。

例如:1分钟= 0.02小时,40分钟= 0.67小时

在此之后,您可以与您的查询相关联,以帮助您。

答案 1 :(得分:0)

这可以为您提供您所要求的声音。我敢肯定可能有更好的解决方案,但这可以作为一种方式进入我的脑海。大部分是我创建临时表的地方。从星号下来是执行工作的查询。

--created a table filled with the dates of every day between now and the 14th.
DECLARE @days datetime
SET @days = GETDATE()
CREATE TABLE #daylist (
dateofwork datetime)
WHILE @days < '02/14/2014'
  BEGIN
    SELECT @days
    INSERT INTO #daylist (dateofwork)
    VALUES (@days)
    SET @days = DATEADD(d, 1, @days)
  END

--created a table of employees with work dates and times
CREATE TABLE #emps (
ID varchar(10),
timein varchar(10),
timedone varchar(10),
dateofwork datetime
)
--inserted values for that table
INSERT INTO #emps (ID, timein, timedone, dateofwork)
VALUES ('123', '08:00', '17:00', '02/12/2014'),
   ('789', '07:00', '18:00', '02/11/2014')

--********************************************************
--used this to get each employee matched with every date showing
--00:00 on all the days they didn't work
SELECT CONVERT(varchar,d.dateofwork,101) AS dateofwork, 
t.ID,
ISNULL(timein, '00:00') AS timein, 
ISNULL(timedone, '00:00') AS timedone
FROM  #daylist d 
   INNER JOIN (SELECT e.ID, d.dateofwork
              FROM #emps e, #daylist d) AS t ON CONVERT(varchar,d.dateofwork,101) =     CONVERT(varchar,t.dateofwork,101)
   LEFT JOIN #emps e ON CONVERT(varchar,e.dateofwork,101) =     CONVERT(varchar,t.dateofwork,101)
          AND e.ID = t.id
ORDER BY dateofwork