2014-11-05 2 views
0

я следующий SQL-запрос (написан другим человеком):2 Количество в одном запросе

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   ??? 

Зачем и как исправить это?

ответ

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

Это потому, что вы в основном только подсчет строк в группе, и группа является для каждой из этих идентификаторов. Если вы просто хотите, итоги, можно использовать DISTINCT рассчитывать различные идентификаторы:

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 этой строки.

Смежные вопросы