显示时间为负面

时间:2014-01-23 06:56:05

标签: sql sql-server tsql sql-server-2012

问题:如果总工作时间大于08:00,我已经成功计算了一个人工作的TotalTime和加班时间,但是如果不超过该工作人员加班时间00:00,那么我现在没有想要这个,我想如果人们工作时间少于8小时,那么加班时间表应该显示为负时间,例如如果有人工作7:00小时,超时时间列应显示-1(以适当的小时格式)

输出:

enter image description here

代码:

with times as (
SELECT    t1.EmplID
        , t3.EmplName
        , min(t1.RecTime) AS InTime
        , max(t2.RecTime) AS [TimeOut]
        , 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 
group by 
          t1.EmplID
        , t3.EmplName
        , t1.RecDate
)
SELECT EmplID
,EmplName
,InTime
,[TimeOut]
,[DateVisited]
,convert(char(5),cast([TimeOutSub] - InTimeSub as time), 108) totaltime
,convert(char(5), case when TimeOutSub - InTimeSub >= '08:01' then 
cast(TimeOutSub - dateadd(hour, 8, InTimeSub) as time) else '00:00' end, 108) as overtime
FROM times

5 个答案:

答案 0 :(得分:0)

然后查询的最后一部分如下所示:

SELECT EmplID
  ,EmplName
  ,InTime
  ,[TimeOut]
  ,[DateVisited]
  ,convert(char(5),cast([TimeOutSub] - InTimeSub as time), 108) totaltime
  ,convert(char(6), 
     CASE WHEN TimeOutSub - InTimeSub >= '08:00' 
          THEN convert(char(5),cast(TimeOutSub - dateadd(hour, 8, InTimeSub) as time)) 
          ELSE '-' + convert(char(5),'08:00' - CAST(TimeOutSub-InTimeSub AS time)) 
     END
   ,108) as overtime
FROM times

答案 1 :(得分:0)

加班计算

 case when cast([TimeOutSub] - InTimeSub as time) <  CAST('08:00' AS TIME) then '-' + convert(char(5), cast(dateadd(hour, 0, '08:00' ) - ([TimeOutSub] - InTimeSub) as time), 108) ELSE convert(char(5), (TimeOutSub- InTimeSub )   - cast(dateadd(hour, 0, '08:00' ) as time), 108)   end as overtime

上次查询

SELECT EmplID
,EmplName
,InTime
,[TimeOut]
,[DateVisited]
,convert(char(5),cast([TimeOutSub] - InTimeSub as time), 108) totaltime
,case when cast([TimeOutSub] - InTimeSub as time) <  CAST('08:00' AS TIME) then '-' + convert(char(5), cast(dateadd(hour, 0, '08:00' ) - ([TimeOutSub] - InTimeSub) as time), 108) ELSE convert(char(5), (TimeOutSub- InTimeSub )   - cast(dateadd(hour, 0, '08:00' ) as time), 108)  end as overtime
FROM times

代码已更改。试试吧。

答案 2 :(得分:0)

试试这个

with times as (
SELECT    t1.EmplID
        , t3.EmplName
        , min(t1.RecTime) AS InTime
        , max(t2.RecTime) AS [TimeOut]
        , 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 
group by 
          t1.EmplID
        , t3.EmplName
        , t1.RecDate
)
SELECT EmplID
,EmplName
,InTime
,[TimeOut]
,[DateVisited]
,convert(char(5),cast([TimeOutSub] - InTimeSub as time), 108) totaltime
,convert(char(5), case when TimeOutSub - InTimeSub >= '08:01' then 
cast(TimeOutSub - dateadd(hour, 8, InTimeSub) as time) else cast(8 - (TimeOutSub - InTimeSub) as time) end, 108) as overtime
FROM times

答案 3 :(得分:0)

-- Try This, I just changed the condition of case TimeOutSub - InTimeSub <> '08:00'
-- and character length to 6 for negative value, All the Best!!!
with times as (
SELECT    t1.EmplID
    , t3.EmplName
    , min(t1.RecTime) AS InTime
    , max(t2.RecTime) AS [TimeOut]
    , 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 
group by 
      t1.EmplID
    , t3.EmplName
    , t1.RecDate
)
SELECT EmplID
,EmplName
,InTime
,[TimeOut]
,[DateVisited]
,convert(char(5),cast([TimeOutSub] - InTimeSub as time), 108) totaltime
,convert(char(6), 
case when TimeOutSub - InTimeSub <> '08:00' then cast(TimeOutSub - dateadd(hour, 8,     InTimeSub) as time)          
     else '00:00' end, 108) as overtime
FROM times

答案 4 :(得分:0)

我再次说使用函数来计算工作时间&amp;随着时间的推移,我在上一个问题中分享了这一点,使用它可以轻松管理&amp;根据您的要求更改,尝试此脚本(例如8小时= 480分钟)

    CREATE FUNCTION GetWorkHours(@INTime AS DateTime, @OutTime AS DateTime,@WorkingHrsINMinutes AS INT)
    RETURNS @WorkHours TABLE
    (
         WorkHours   Varchar(6),  
         OTHours     Varchar(6)
    )
    AS
    BEGIN
    INSERT INTO @WorkHours
    SELECT CAST((DATEDIFF(Minute, @INTime, @OutTime)) / 60 AS VARCHAR(2))+ ':' 
           + CAST((DATEDIFF(Minute, @INTime, @OutTime)) % 60 AS VARCHAR(2)) AS TotalTime,
           CASE
           WHEN DATEDIFF(Minute, @INTime, @OutTime)  > @WorkingHrsINMinutes 
                THEN CAST((DATEDIFF(Minute, @INTime, @OutTime) -@WorkingHrsINMinutes) / 60 AS VARCHAR(2))+ ':' +
                     CAST((DATEDIFF(Minute, @INTime, @OutTime) -@WorkingHrsINMinutes) % 60 AS VARCHAR(2)) 
           WHEN DATEDIFF(Minute, @INTime, @OutTime)  < @WorkingHrsINMinutes 
                THEN '-' +
                     CAST((DATEDIFF(Minute, @INTime, @OutTime) -@WorkingHrsINMinutes) / 60 AS VARCHAR(2))+ ':' +
                     CAST((ABS(DATEDIFF(Minute, @INTime, @OutTime) -@WorkingHrsINMinutes)) % 60 AS VARCHAR(2))           
           ELSE '00:00'
           END AS OverTime

    RETURN
    END
    GO

    SELECT * From Dbo.GetWorkHours('2014-01-22 10:00:09.270','2014-01-22 18:10:09.270','480')
    SELECT * From Dbo.GetWorkHours('2014-01-22 10:00:09.270','2014-01-22 17:10:09.270','480')