2013-11-15 64 views
0

我试图估计人们在一段时间内工作了多少小时。我想按部门和他们进行的工作是什么区域,以显示这个现在我有这样的:按部门划分的每小时和平均每小时工作时间

SELECT M.MemberDepartmentID,T.TaskName, 
    COUNT(DATEDIFF(HOUR, TT.StartTime, TT.EndTime)) 'Hours', 
    AVG(DATEDIFF(HOUR, TT.StartTime, TT.EndTime)) Average 
FROM Member.TaskTracking TT 
    LEFT OUTER JOIN Member.Task T 
     ON TT.TaskID=T.TaskID 
    JOIN dbo.tblMember M 
     ON TT.MemberID=M.MemberID 
WHERE M.FullTime=1 
    AND M.EmployeeSalary=1 
    AND (TT.StartTime >= '2013-10-01' 
    AND TT.EndTime < '2013-11-01') 
GROUP BY M.MemberDepartmentID,T.TaskName 
ORDER BY M.MemberDepartmentID,T.TaskName 

我不知道如何来确认是否是正确的,但有些肯定出甚至零平均值如果有工作小时。有些平均值比工作时间长。例如,以下是我的一些结果:

MemberDepartmentID TaskName  Hours Average 
--------------------------------------------------- 
1     Packing   25  0 
1     Picking   6  0 
1     PreScanning  38  7 
4     Picking   2  104 

建议?

+0

开始和结束时间始终在数据库中有值吗? – StingyJack

+3

你的意思是使用计数?如果你想知道我工作了多少小时,我想你想用一笔钱。伯爵只会告诉你有多少事件,但他们可能都是零。 – Andrew

+0

@SingyJack - 是的,他们做 – ash

回答

8

首先,重要的是要注意DATEDIFF(HOUR)返回一个整数,它不一定能够很好地反映实际经过了多少时间。例如,这些都产生1

SELECT DATEDIFF(HOUR, '03:59', '04:01'); -- 2 minutes (0.033333 hours) 

SELECT DATEDIFF(HOUR, '03:01', '04:59'); -- 118 minutes (1.966666 hours) 

而这些都产生出0:

SELECT DATEDIFF(HOUR, '03:01', '03:59'); -- 58 minutes (0.966666 hours) 

SELECT DATEDIFF(HOUR, '03:01', '03:02'); -- 1 minute (0.016666 hours) 

接下来,如果你给SQL Server的整数来划分,它要执行整数运算。这意味着它会分裂,但它会放弃任何剩余。这会产生0:

SELECT 3/4; 

即使真的是0.75,如果四舍五入应该是1(不,无论这些结果是特别有意义的)。现在,扩大到平均水平。

DECLARE @d1 TABLE(a INT); 

INSERT @d1 VALUES(3),(4); 

SELECT AVG(a) FROM @d1; 

这将产生3,而不是3.5,你可能会期望。出于与上述相同的原因。记住你的一些任务可能持续了长达59分钟,但仍然会产生0小时差,你可以有4个任务,3个持续大于1小时,1个持续1个小时,并且持续时间为< 1小时。所以,你的平均计算将基本上是:

SELECT (1+1+1+0)/4; 

,如上,仍然得到0

如果你想有一个有意义的平均那里,你应该计算所花的时间更精细比小时。例如,你可以在几分钟内进行DATEDIFF:

SELECT DATEDIFF(MINUTE, '03:01', '04:59'); 

这将产生118。如果你想表达的是,在个小时,你可以用60.0分(小数点是很重要的),或1.0乘以:

SELECT DATEDIFF(MINUTE, '03:01', '04:59')/60.0; 

SELECT 1.0*DATEDIFF(MINUTE, '03:01', '04:59')/60; 

这些产量均为1.966666。平均这样的结果更有意义。所以,你的表达可能更改为:

Average = AVG(1.0*DATEDIFF(MINUTE, TT.StartTime, TT.EndTime)/60) 

关于计数,不知道你试图做什么有,但你可能要作出类似调整,计算可能考虑使用SUM。如果您显示一些示例数据和您期望的结果,我们可以提供更多帮助。

此外,我建议不要使用'single quotes'转义关键字别名 - 这种语法的某些形式已被弃用,它使您的别名看起来像字符串文字。首先,尽量不要使用关键字或其他无效标识符作为别名;但如果你必须的话,请用[square brackets]逃脱它们。

+0

哇,非常感谢你的所有建议! – ash