SQL查询中的计数问题

时间:2011-02-04 02:15:26

标签: sql

我想创建一个查询,显示员工的姓名以及所有未关闭的服务的总和。查询结果没有给我正确的值。

这是我的问题:

SELECT DISTINCT 
       a.AssignedEmp, 
       COUNT( a.TipoStatus ) AS 'Service Request Count'
   FROM Service a, 
        employee b  
  WHERE b.Classification_ClassificationID = 2 
    AND a.TipoStatus = 'Open'
     OR a.TipoStatus = 'Pending'
     OR a.TipoStatus = 'Hold'
     OR a.TipoStatus = 'Warranty'
    AND a.AssignedEmp = b.UserName
 GROUP BY a.AssignedEmp
    LIMIT 0, 30

结果是这个查询给了我:

dpadil    16
epadil     8

正确的值应该是2和1.

3 个答案:

答案 0 :(得分:3)

首先你要做的就是摆脱countgroup by

这将为您提供正在使用的实际,并可能直接向您显示问题。

比率正确(16:8 = 2:1)这一事实通常表明AND a.AssignedEmp = b.UserName并不像您想象的那样限制。

换句话说,跨表连接更加丰富。将行自己排除在外可以帮助您理解原因。

答案 1 :(得分:2)

你的OR'd条件需要括号(并且应该使用JOIN表示法):

SELECT DISTINCT 
       a.AssignedEmp, 
       COUNT( a.TipoStatus ) AS 'Service Request Count'
  FROM Service AS a
  JOIN employee AS b ON a.AssignedEmp = b.UserName
 WHERE b.Classification_ClassificationID = 2 
   AND (a.TipoStatus = 'Open'
    OR  a.TipoStatus = 'Pending'
    OR  a.TipoStatus = 'Hold'
    OR  a.TipoStatus = 'Warranty')
 GROUP BY a.AssignedEmp
 LIMIT 0, 30

或者你可以直接用“未关闭”来写条件:

SELECT DISTINCT 
       a.AssignedEmp, 
       COUNT( a.TipoStatus ) AS 'Service Request Count'
  FROM Service AS a
  JOIN employee AS b ON a.AssignedEmp = b.UserName
 WHERE b.Classification_ClassificationID = 2 
   AND a.TipoStatus != 'Closed'
 GROUP BY a.AssignedEmp
 LIMIT 0, 30

正如最初编写的那样,WHERE子句相当于:

WHERE (b.Classification_ClassificationID = 2 AND a.TipoStatus = 'Open')
   OR a.TipoStatus = 'Pending'
   OR a.TipoStatus = 'Hold'
   OR (a.TipoStatus = 'Warranty' AND a.AssignedEmp = b.UserName)

这将为用户计算分类ID为2的所有Open服务项目;它还会计算所有待处理服务项目,无论分类ID如何,所有保留服务项目,无论分类ID如何,以及分配给用户的所有保修服务项目,无论分类ID如何。 GROUP BY会对事物进行过滤,以便只计算具有正确分配的员工的项目,但某些术语存在部分交叉产品,从而导致计数膨胀。

答案 2 :(得分:0)

您可能希望更明确地构建您的条件。

您还应使用JOIN语句指定JOIN条件,而不是其他条件。

SELECT DISTINCT         
a.AssignedEmp,         
COUNT( a.TipoStatus ) AS 'Service Request Count'    
FROM Service a
       INNER JOIN employee b
       ON a.AssignedEmp = b.UserName  
WHERE b.Classification_ClassificationID = 2      
    AND (
        a.TipoStatus = 'Open'      
        OR a.TipoStatus = 'Pending'      
        OR a.TipoStatus = 'Hold'      
        OR a.TipoStatus = 'Warranty'
        )
GROUP BY a.AssignedEmp     
    LIMIT 0, 30