如何计算sql中的条目“就像在循环中”

时间:2016-02-04 08:17:59

标签: sql postgresql count

首先,我对数据库非常陌生,所以这可能是一个非常简单的问题,但我不知道如何谷歌或如何给它一个好的标题。我正在使用python的postgres,但问题是将正确的查询放在一起。

方案如下。我有一个包含列的表:ID,Trial,Subject,Invalid。它来自一个行为实验,许多科目执行由几个试验组成的任务。由于不同的原因,它们的响应可能无效,并且根据原因存在不同的失效代码(整数)。有效响应的代码为0.

------------------------------
ID | SUBJECT | TRIAL | INVALID  
------------------------------
1    Peter     1       0  
2    Peter     2       0  
3    Peter     3       1  
4    Peter     4       3
5    Mary      1       3  
6    Mary      2       2  
7    Mary      3       0  
8    Mary      4       2

我想做两件事(我不确定如何以优雅的方式做)。

a)对于每个主题,我想知道总共有多少回复以及有多少回复。现在我正在对每个主题进行查询,条件是,例如,WHERE Subject ='Peter',但我可以想象有一个更优雅的解决方案。

示例答案:

Subject Valids Total
Peter   2      4
Mary    1      4

b)对于每个科目,我想知道每个失效代码有多少回复无效。理想情况下,我会得到一个像这样的表:

Subject Invalid Count
Peter   0       2
Peter   1       1
Peter   2       0
Peter   3       1
Mary    0       1
Mary    1       0
Mary    2       2
Mary    3       1

1 个答案:

答案 0 :(得分:2)

查询#1:您希望每个主题有一个结果行,因此您可以按主题分组。使用COUNT计算主题的所有记录,COUNT与CASE结合使用以有条件地计数(所有有效记录)。

select 
  subject, 
  count(*) as all_responses, 
  count(case when invalid = 0 then 1 end) as valid_responses
from mytable
group by subject;

查询#2:在这里,您需要每个主题和代码一个结果行,因此您可以按这两个进行分组。然后用COUNT计算。

select 
  subject, 
  invalid,
  count(*) as responses
from mytable
group by subject, invalid;

更新:在您更新的请求中,您希望查询#2显示所有主题/代码组合,即使它们的计数为0.为了做到这一点,您必须创建首先设置所有有效组合,然后外连接您的响应表:

select 
  s.subject, 
  c.code,
  count(m.invalid) as responses
from subjects s
cross join codes c
left join mytable m on (m.subject = subjects.subject and m.invalid = codes.code)
group by s.subject, c.code;

如果您没有主题和代码表(您应该这样),您可以从响应表中获取它们:

select 
  s.subject, 
  c.code,
  count(m.invalid) as responses
from (select distinct subject from mytable) s
cross join (select distinct invalid as code from mytable) c
left join mytable m on (m.subject = subjects.subject and m.invalid = codes.code)
group by s.subject, c.code;