【问题标题】:new column to calculate overtime计算加班的新列
【发布时间】:2014-01-22 19:00:26
【问题描述】:

我编写并管理了这个查询,以通过 dateDiff 函数计算一个人每天工作的总时间,现在我被困在一个地方。我想计算一下,如果一个人随着时间的推移已经完成,那么新列应该在 hh:mm 中显示 OVERITME。

我们办公室的总工作时间为 08:00,超过 8 小时被视为加班,例如如果一个人的工作时间是 08:35,那么一列应该显示一个人的工作时间是 00:35

查询:

with times as (
SELECT    t1.EmplID
        , t3.EmplName
        , min(t1.RecTime) AS InTime
        , max(t2.RecTime) AS [TimeOut]
        , 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]
                ,CASE 
                    WHEN minpart = 0
                        THEN CAST(hourpart AS NVARCHAR(200)) + ':00'
                    WHEN minpart <10
                        THEN CAST(hourpart AS NVARCHAR(200)) + ':0'+ CAST(minpart AS NVARCHAR(200))
                    ELSE CAST(hourpart AS NVARCHAR(200)) + ':' + CAST(minpart AS NVARCHAR(200))

END AS 'total time'
            FROM (
                SELECT EmplID
                    ,EmplName
                    ,InTime
                    ,[TimeOut]
                    ,[DateVisited]
                    ,DATEDIFF(minute, InTime, [TimeOut])/60 AS hourpart
                    ,DATEDIFF(minute, InTime, [TimeOut]) % 60 AS minpart
                FROM times
                ) source

输出:

【问题讨论】:

  • 只是伪代码:您可以使用您的 total_time 并从中减去 8:CASE WHEN total_time - 8 &gt; 0 THEN total_time - 8 ELSE 0 END overtime

标签: sql tsql sql-server-2012


【解决方案1】:

试试这个:

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

【讨论】:

  • 错误:消息 8117,级别 16,状态 1,第 26 行操作数数据类型 char 对减法运算符无效。
  • 你的超时时间和时间不是日期时间吗?
  • 如果你能解释一下这些变化,我会更开心,
  • 108 是什么?我在最后两行看到它
  • 108 是format,其中正在转换/转换结果
【解决方案2】:

你离得太近了,我看不出你为什么会遇到问题!

case...end as total_time之后,添加:

, case when hourpart >= 8 then
            case WHEN minpart = 0
                        THEN CAST((hourpart - 8) AS NVARCHAR(200)) + ':00'
                    WHEN minpart <10
                        THEN CAST((hourpart - 8) AS NVARCHAR(200)) + ':0'+ CAST(minpart AS NVARCHAR(200))
                    ELSE CAST((hourpart - 8) AS NVARCHAR(200)) + ':' + CAST(minpart AS NVARCHAR(200)) end
  else '00:00'
  end as overTime

干杯-

【讨论】:

    【解决方案3】:
    --You can create a separate function to calculate work-hrs and overtime   
    -- Try this
    
    CREATE FUNCTION GetWorkHours (
    @INTime AS DATETIME
    ,@OutTime AS DATETIME
    ,@WorkingHrsINMinutes AS INT
    )
    RETURNS @WorkHours TABLE (
    WorkHours VARCHAR(5)
    ,OTHours VARCHAR(5)
    )
    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))
            ELSE '00:00'
            END AS OverTime
    
        RETURN
    END
    
    --- Sample
    SELECT *
    FROM Dbo.GetWorkHours('2014-01-22 10:00:09.270', '2014-01-22 18:35:09.270', '480')
    
    SELECT *
    FROM Dbo.GetWorkHours('2014-01-22 10:00:09.270', '2014-01-22 17:35:09.270', '480')
    

    【讨论】:

      猜你喜欢
      • 2014-01-04
      • 2021-12-05
      • 1970-01-01
      • 2022-10-24
      • 1970-01-01
      • 1970-01-01
      • 2016-10-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多