我有以下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 ???
为什么以及如何解决这个问题?
答案 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上投票的数量。