2在同一查询中计数

时间:2014-11-05 21:26:09

标签: mysql count

我有以下SQL查询(由其他人编写):

select q.id, q.text, v.id, count(v.id) as voteCount
  from survey as s 
  join sessions as ss on ss.session_state='FINISHED' and ss.survey=s.id
  join answer as a on a.sessionId=ss.id 
  join answer_item as a_i on a_i.answer=a.id 
  join question_variant as v on v.id=a_i.question_variant_id
  join question as q on q.id=v.question_id 
  where s.id=9  
  group by q.id, v.id order by q.id, voteCount desc

它输出调查的统计数据。 9仅用于测试。 voteCount返回为每个问题选择答案变体的次数。它工作正常:

q.id q.text    v.id voteCount comment for voteCount
10   blahblah  5    2         2 is two times (5 and 5) for question 10
10   blahblah  4    1         1 is one time (4) for question 10
10   blahblah  2    1         1 is one time (2) for question 10
10   blahblah  5    2         2 is two time (5 and 5) for question 10
11   foobarfoo 5    1         1 is one time (5) for question 11

现在我想修改查询以在结果中包含另一列,这等于回答问题的次数。

q.id q.text    v.id voteCount totalCount comment for totalCount
10   blahblah  5    2         4          4 is four times question 10 is answered
10   blahblah  4    1         4          4 is four times question 10 is answered
10   blahblah  2    1         4          4 is four times question 10 is answered
10   blahblah  5    2         4          4 is four times question 10 is answered
11   foobarfoo 5    1         1          1 is one time question 11 is answered

我试过这个:

select q.id, q.text, v.id, count(v.id) as voteCount, count(q.id) as totalCount
  from survey as s 
  join sessions as ss on ss.session_state='FINISHED' and ss.survey=s.id
  join answer as a on a.sessionId=ss.id 
  join answer_item as a_i on a_i.answer=a.id 
  join question_variant as v on v.id=a_i.question_variant_id
  join question as q on q.id=v.question_id 
  where s.id=9  
  group by q.id, v.id order by q.id, voteCount desc

但令人惊讶的是,两列都包含相同的值!

q.id q.text    v.id voteCount totalCount comment for totalCount
10   blahblah  5    2         2          ???
10   blahblah  4    1         1          ???
10   blahblah  2    1         1          ???
10   blahblah  5    2         2          ???
11   foobarfoo 5    1         1          ???

为什么以及如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

COUNT()和其他聚合函数在每组的基础上应用。由于q.id和v.id是分组列,因此每个组的计数将分别为该组中的数字结果(如果这些列可以为空,则可能在几个组中为零)。

我不确定我是否理解您要提取的其他信息,但听起来您希望以不同方式对结果进行分组,在这种情况下,您可能需要单独的查询。我只能根据你的问题和你的其他问题来猜测这可能是什么,但也许会是这样的:

select q.id, count(*) as answerCount
from survey as s 
  join sessions as ss on ss.session_state='FINISHED' and ss.survey=s.id
  join answer as a on a.sessionId=ss.id 
  join answer_item as a_i on a_i.answer=a.id 
  join question_variant as v on v.id=a_i.question_variant_id
  join question as q on q.id=v.question_id 
where s.id=9  
group by q.id

答案 1 :(得分:1)

那是因为你基本上只计算组中的行数,并且每个ID的组都是相同的。如果您只想要总计,可以使用DISTINCT计算不同的ID:

select 
  count(distinct v.id) as voteCount, 
  count(distinct q.id) as totalCount
....

但你也是通过q.id和v.id分组来获得问题的个别属性(比如标题),所以COUNT DISTINCT对你没有任何好处。每个结果的结果总是1。您似乎想要使用分析函数(窗口函数),它存在于Oracle和其他各种数据库中,但不存在于MySQL中。

有模拟这些功能的技巧(参见DBA.SE - MySQL and window functions),但在这种情况下,我认为有两个子选择可以帮到你:

select 
  q.id, 
  q.text, 
  v.id, 
  (select
    count(vx.id)
  from
    question_variant vx
  where
    vx.id = v.id) as VoteCount,
  (select
    count(qx.id)
  from
    question qx
  where
    qx.id = q.id) as TotalCount
from 
  survey as s 
  join sessions as ss on ss.session_state='FINISHED' and ss.survey=s.id
  join answer as a on a.sessionId=ss.id 
  join answer_item as a_i on a_i.answer=a.id 
  join question_variant as v on v.id=a_i.question_variant_id
  join question as q on q.id=v.question_id 
where 
  s.id=9  
group by 
  q.id, v.id 
order by 
  q.id, 
  voteCount desc

您可以在此查询中使用group by,而不是select distinct。重点是,您选择了您喜欢的所有字段,并且对于每一行,您分别计算回答该行的问题的次数以及该行的question_variant上投票的数量。