1

と の 2 つのテーブルがありquestionますanswer。でanswerと を保持user_idquestion_idます。各選択肢が選択された回数を数えたい。

以下は実際のクエリですが、同じテーブルを 4 回結合する代わりに、回答テーブルを 1 回だけ結合するより高速な方法があります。

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 と評価されない場合、ユーザー IDNULLに含まれない が返されるためです。COUNT DISTINCT

于 2012-12-05T19:15:05.373 に答える
0

パフォーマンスが気になる場合は、SELECT... UNION SELECT スタイルの使用を検討してください。

依存クエリがないため、オプティマイザーが何を言っているのかを確認するには、結果を説明する必要があるという@benjamに同意します。

于 2012-12-05T18:39:35.780 に答える
0

、 、 、、question.question_idおよび にインデックスがあることを確認してください。クエリは、各選択肢の回答に参加しない他のクエリと同じくらい高速である必要があります。次に、次のクエリを使用します。answer.question_idanswer.choiceanswer.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 に答える