用于计算3种不同条件下的行的SQL查询

时间:2013-12-30 09:06:40

标签: sql postgresql select count group-by

所以我想创建一个查询,它会返回projects的名称和assigments的与特定严重性project相关的名称。例如:表assigment包含:

 id  |                name                 | project_id  | severity  | 
-----+-------------------------------------+-------------+-----------+
 148 | Create background                   |         1   |          1|  
 184 | Create frontend                     |         1   |          1|  
 151 | Create Budged                       |         1   |          2|  
 155 | Assign all tasks                    |         1   |          3|    
 179 | Drink Beer                          |         1   |          1|   

project仅包含nameid,如下所示:

 id  |                name                 
-----+-------------------------------------
 1   | Very Important Project

我想创建一个返回类似的查询:

projectid   |  projectname          | CriticalAssig| MediumAssig | LowAssig
------------+-----------------------+--------------+-------------+----------

目前这对我有用:

SELECT p.id, 
       p.name, 
       Count(a1.id)  AS one, 
       Count(a2.id)  AS two, 
       Count (a3.id) AS three 
FROM   project p 
       INNER JOIN assign a1 
               ON a1.project_id = p.id 
       INNER JOIN assign a2 
               ON a2.project_id = p.id 
       INNER JOIN assign a3 
               ON a3.project_id = p.id 
WHERE  a2.severity = '2' 
       AND a1.severity = '1' 
       AND a3.severity = '3' 
GROUP  BY p.id, 
          p.name; 

但是这个查询的结果在onetwothree列中是荒谬的,我得到了90000之类的数字(到处都是相同的数字)而简单查询{{ 1}}返回select count(*) from assig where project_id=x

有人能指出我的错误所在吗?

4 个答案:

答案 0 :(得分:4)

您可以在没有任何连接的情况下执行此操作:

count(case when severity = 1 then 1 else null end) as one

(您当前查询中的问题是您在分组之前将行数相乘。在开发聚合时,运行查询而不进行聚合函数调用和分组by / having子句,以查看实际计算的内容,求和等。)

答案 1 :(得分:3)

试试这个:

SELECT p.id, p.name, 
       SUM(a.severity = 1) AS one, 
       SUM(a.severity = 2) AS two, 
       SUM(a.severity = 3) AS three
FROM project p 
INNER JOIN assign a ON a.project_id = p.id  
GROUP BY p.id, p.name

SELECT p.id, p.name, 
       SUM(CASE WHEN a.severity = 1 THEN 1 ELSE 0 END) AS one, 
       SUM(CASE WHEN a.severity = 2 THEN 1 ELSE 0 END) AS two, 
       SUM(CASE WHEN a.severity = 3 THEN 1 ELSE 0 END) AS three
FROM project p 
INNER JOIN assign a ON a.project_id = p.id  
GROUP BY p.id, p.name

答案 2 :(得分:2)

试试这个

select p.id, 
p.name, 
count(case when severity = 1 then 1 else null end) as one, 
count(case when severity = 2 then 1 else null end) as two, 
count (case when severity = 3 then 1 else null end) as three
    from project p 
    inner join assign on assign.project_id = p.id 
    group by p.id, p.name;

答案 3 :(得分:1)

您需要使用子查询。

select p.id, p.name, 
count(SELECT * FROM project a where severity = 1 and p.id=a.id) as one, 
count(SELECT * FROM project a where severity = 2 and p.id=a.id) as two, 
count(SELECT * FROM project a where severity = 3 and p.id=a.id) as three
from project p
group by p.id, p.name;