2012-06-06 76 views
3
SELECT  u.FirstName + ' ' + u.LastName as 'User', 
      COUNT(*) as 'Number of Calls', 
      CONVERT(varchar(4), SUM(CASE WHEN c.FromTime BETWEEN @FromDate AND @ToDate 
       THEN DATEDIFF(mi, c.FromTime, c.ToTime) ELSE 0 END)/60) + ':' + 
      CASE WHEN SUM(CASE WHEN c.FromTime BETWEEN @FromDate AND @ToDate 
       THEN DATEDIFF(mi, c.FromTime, c.ToTime) ELSE 0 END) % 60 < 10 THEN '0' ELSE '' END + 
      CONVERT(varchar(2), SUM(DATEDIFF(mi, c.FromTime, c.ToTime)) % 60) as 'Total Time Spent', 
      CONVERT(varchar(4), AVG(DATEDIFF(mi, c.FromTime, c.ToTime))/60) + ':' + 
      CASE WHEN AVG(DATEDIFF(mi, c.FromTime, c.ToTime)) % 60 < 10 THEN '0' ELSE '' END + 
      CONVERT(varchar(2), AVG(DATEDIFF(mi, c.FromTime, c.ToTime)) % 60) as 'Average Call Time' 
FROM  Calls c 
JOIN  Users u ON u.UserID = c.TakenBy 
WHERE  c.FromTime BETWEEN @FromDate AND @ToDate 
GROUP BY u.UserID, u.FirstName, u.LastName 
ORDER BY u.FirstName + ' ' + u.LastName 

前面的SQL查询返回正确的“呼叫数量”,但“总时间”和“平均时间”都是一样的,无论呼叫#的(这显然是错误的)。SQL SUM()函数忽略WHERE子句和CASE语句

我读过并尝试使用CASE WHEN __然后在SUM内部赋值ELSE 0,但它仍然返回一个不正确的值。

我能得到这个查询返回正确结果的唯一方法是,如果我完全去除所有其他信息,例如

SELECT SUM(DATEDIFF(mi, FromTime, ToTime)) FROM Calls WHERE c.FromTime BETWEEN... 

如何仍然可以使用我的JOIN和GROUP BY并获得聚合函数来给我我想要的结果?

感谢您的帮助!

+0

我认为你正在试图在选择列中做太多的事情, 你可以尝试将这一点分解成子查询吗? – zinking

+3

为了澄清这个建立一个选择您的目标值第一。在那里检查正确的结果。之后你将他们分组并总结/平均列。 – YvesR

+0

我同意上面的评论者,你需要简化你的示例代码来尝试找到问题。因此,如果您可以在没有额外CASE语句的情况下重新发布您的示例SQL(反正这不应该是必需的)。 –

回答

0

你可能最好用子查询,例如在SELECT部分​​中添加如(SELECT SUM(...) FROM ... WHERE ...) AS total_sum