2016-09-16 64 views
0

的总和我有一个表TEST需要计算加班

AccountName AccountIndex AccountID StartTime EndTime  checkouttime     
ABC    3    7  07:00:00.00 16:00:00.00 2016-07-22 17:03:00  
ABC    3    7  07:00:00.00 16:00:00.00 2016-07-23 16:00:00  
ABC    3    7  07:00:00.00 16:00:00.00 2016-07-25 17:04:00  

我要计算加班的总和。

我想这

select name,accountid,case when (cast(CheckOutTime as time) < EndTime) then '-' else '' end + 
convert(varchar(8), 
    dateadd(minute, 
    abs(
    DATEDIFF(minute, 
    cast(CheckOutTime as time) 
    , EndTime) 
    ) 
,0) 
,108) as Overtime 
from test 

,我得到的O/P为

name accountid Overtime  
ABC  7   01:03:00 
ABC  7   00:00:00 
ABC  7   01:04:00 

我想有一个像加班

name accountid Overtime  
ABC   7  02:07:00  

总和O/P如何做到这一点

+0

告诉它由两个人来总结的价值和组,像往常一样 –

+0

@SamiKuhmonen我已经尝试过案件时(cast(sum(CheckOutTime as time))

+0

将总和作为最外层函数,因为您正在对结果进行求和 –

回答

1
select accountid,name,cast((totalseconds/3600) as varchar) + ':' + cast(((totalseconds%3600)/60) as varchar) as overtime 
from 
(
select accountid,name, 
      sum(Datediff(s,Endtime,cast(checkouttime as time))) as totalseconds 
    group by accountid,name 
    ) t 

使用上面的查询,计算加班

+0

它正在计算像accountid \t加班 03:00:00:000其计算不正确 –

+0

@RedDevil列名在myquery中不正确。修改我的查询。请现在检查 –

+0

它给我一个错误转换varchar值':'到数据类型int转换失败。 –

0

SUM不适用于时间数据类型。

您可以通过组名的数据,帐户ID和使用

SUM(DATEDIFF(ss, '00:00:00.000', [your overtime value]))

找到的总秒数,并最终转换成秒数回时间DATEADD()函数。

UPDATE:

select 
    acc_id, 
    name, 
    CONVERT(VARCHAR(20), DATEADD(ss, SUM(DATEDIFF(ss, '00:00:00.000', [your overtime value])), '00:00:00'), 114) as overtime 
from [your table] 
group by acc_id, name 

如果你期望的加班可能会超过24小时,一个ACC_ID,那么你可以添加其他栏,显示的天(秒/(3600 * 24号号) )

1
Declare @YourTable table (AccountName varchar(50),AccountIndex int,AccountID int,StartTime varchar(25),EndTime varchar(25), checkouttime datetime) 
Insert into @YourTable values 
('ABC',3,7,'07:00:00.00','16:00:00.00','2016-07-22 17:03:00'), 
('ABC',3,7,'07:00:00.00','16:00:00.00','2016-07-23 16:00:00'),  
('ABC',3,7,'07:00:00.00','16:00:00.00','2016-07-25 17:04:00') 

Select AccountName 
     ,AccountID 
     ,OverTime = cast(DateAdd(MINUTE,sum(DateDiff(MINUTE,cast(EndTime as time),case when cast(EndTime as time)>cast(checkouttime as time) then cast(EndTime as time) else cast(checkouttime as time) end)),'00:00:00') as time) 
From @YourTable  
Group By AccountName,AccountID 

返回

AccountName AccountID OverTime 
ABC   7   02:07:00.0000000 

对于一个更可读的一个,你可以使用一个CTE。

;with cteBase as (
    Select AccountName 
      ,AccountID 
      ,EndTime  =cast(EndTime as time) 
      ,checkouttime=cast(checkouttime as time) 
    From @YourTable 
) 
Select AccountName 
     ,AccountID 
     ,OverTime = cast(DateAdd(MINUTE,sum(DateDiff(MINUTE,EndTime,case when EndTime>checkouttime then EndTime else checkouttime end)),'00:00:00') as time) 
From cteBase  
Group By AccountName,AccountID 
+0

这里有1个问题,如果超时超过23:59:59那么它再次从0开始,这使得总和功能不正确 –

+0

如果超过24,我们可以总结25小时 –

+0

@RedDevil只是格式化的问题。给我一点时间 –

0

它也将满足您的要求,所以请尽量与此还有:(只适用2012年)

SELECT AccountName, AccountID, 
    CONCAT(t.tot/60, ':', t.tot%60,':00') orverTime 
FROM (
    SELECT AccountName, AccountID, 
    SUM(DATEDIFF(mi, CONCAT(SUBSTRING(
    CAST(checkouttime AS VARCHAR(50)), 1, 11), ' ', EndTime), 
    checkouttime)) tot 
FROM #tmp 
GROUP BY AccountName, AccountID) t 
+0

这给了我一个错误'CONCAT'不是一个公认的内置函数名称。 –

+0

您是否尝试过完全相同,因为它在SQL Server 08和12中测试的地方工作正常。有一点,CONCAT是SQL Server公认的功能。请重新验证它。 – Susang

+0

我在2008年和2012年都试过这两个查询在2012年都有效,但在2008年给出了一个错误 –