首先,我对数据库非常陌生,所以这可能是一个非常简单的问题,但我不知道如何谷歌或如何给它一个好的标题。我正在使用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
答案 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;