1

有两个表:questionanswer。在answer我持有user_idquestion_id。我想计算每个选项被选中的次数。

下面是一个有效的查询,但不是将同一个表加入 4 次,而是一种更快的方法,即只加入一次答案表。

SELECT question.question_id,
    question.correct_choice,
    COUNT(DISTINCT a.user_id) as num_of_a,
    COUNT(DISTINCT b.user_id) as num_of_b,
    COUNT(DISTINCT c.user_id) as num_of_c,
    COUNT(DISTINCT d.user_id) as num_of_d
FROM answer a,
    answer b, 
    answer c, 
    answer d,
    question 
WHERE a.question_id = question.question_id 
    AND b.question_id = question.question_id
    AND c.question_id = question.question_id 
    AND d.question_id = question.question_id 
    AND a.choice = 'A' 
    AND b.choice = 'B'
    AND c.choice = 'C' 
    AND d.choice = 'D'  
GROUP BY question.question_id 
ORDER BY question.question_id asc;

返回

273, D, 5, 2, 8, 39
274, C, 2, 14, 50, 2
277, C, 3, 5, 41, 17
278, C, 16, 9, 34, 9
279, C, 8, 30, 24, 12
280, B, 17, 21, 20, 3
284, C, 2, 3, 19, 1
286, A, 16, 3, 2, 2
287, D, 1, 2, 1, 18
289, B, 3, 18, 2, 2
290, D, 6, 9, 8, 6
4

3 回答 3

1

此解决方案仅进行一次连接...此外,我将您的隐式连接转换为显式连接,并完善了您的GROUP BY

SELECT 
    q.question_id,
    q.correct_choice,
    COUNT(DISTINCT CASE WHEN a.choice = 'A' THEN a.user_id END) as num_of_a,
    COUNT(DISTINCT CASE WHEN a.choice = 'B' THEN a.user_id END) as num_of_b,
    COUNT(DISTINCT CASE WHEN a.choice = 'C' THEN a.user_id END) as num_of_c,
    COUNT(DISTINCT CASE WHEN a.choice = 'D' THEN a.user_id END) as num_of_d
FROM 
    answer a
    JOIN question q ON a.question_id = q.question_id
GROUP BY q.question_id, q.correct_choice
ORDER BY q.question_id asc;

这是有效的,因为当CASE语句的计算结果不为 true 时,它​​会返回NULL,它不会包含在COUNT DISTINCT用户 ID 中。

于 2012-12-05T19:15:05.373 回答
0

如果您关心性能,您可以考虑使用 SELECT... UNION SELECT 样式。

尽管我同意@benjam 的观点,您应该解释结果以查看优化器在说什么,因为您没有依赖查询。

于 2012-12-05T18:39:35.780 回答
0

确保您在question.question_id、 和 、 和 上有索引answer.question_idanswer.choice并且answer.user_id您的查询应该与不加入每个选择答案的任何其他查询一样快。然后使用以下查询:

SELECT `question`.`question_id`,
    `question`.`correct_choice`,
    COUNT(DISTINCT `a`.`user_id`) as `num_of_a`,
    COUNT(DISTINCT `b`.`user_id`) as `num_of_b`,
    COUNT(DISTINCT `c`.`user_id`) as `num_of_c`,
    COUNT(DISTINCT `d`.`user_id`) as `num_of_d`
FROM `question`
    LEFT JOIN `answer` AS `a`
        USING(`a`.`question_id` = `question`.`question_id`
            AND `a`.`choice` = 'A'),
    LEFT JOIN `answer` AS `b`
        USING(`b`.`question_id` = `question`.`question_id`
            AND `b`.`choice` = 'B'),
    LEFT JOIN `answer` AS `c`
        USING(`c`.`question_id` = `question`.`question_id`
            AND `c`.`choice` = 'C'),
    LEFT JOIN `answer` AS `d`
        USING(`d`.`question_id` = `question`.`question_id`
            AND `d`.`choice` = 'D')
GROUP BY `question`.`question_id` ;

ORDER BY 子句不需要并且从 GROUP BY 子句中隐含。

于 2012-12-05T18:45:49.153 回答