遇到MySQL查询问题

时间:2012-08-30 07:37:14

标签: mysql sql database

需要生成课程列表并计算

  1. 所有
  2. 未应答
  3. 已解答但未经检查
  4. 问题。

    这是我的查询

    SELECT c.id, 
        c.name, 
        COUNT(allq.id) 'All', 
        COUNT(unanswered.id) 'Unanswered',
        COUNT(unchecked.id) 'Unchecked'
    FROM courses c
    LEFT JOIN `courses-lessons` cl 
        ON c.id = cl.cid
    LEFT JOIN lesson_questions allq 
        ON cl.id = allq.lid
    LEFT JOIN
    (
        SELECT q.id, a.qid, q.lid
        FROM lesson_questions q
        LEFT JOIN 
        (
            SELECT id, qid
            FROM answers
            WHERE id NOT IN (SELECT aid FROM answer_chk_results)
        ) a 
            ON q.id = a.qid 
    ) unchecked 
        ON cl.id = unchecked.lid
    LEFT JOIN
    (
        SELECT id
        FROM lesson_questions
        WHERE id NOT IN (SELECT qid FROM answers)
    ) unanswered 
        ON cl.id = unchecked.lid
    GROUP BY c.id, c.name
    

    这是一个SQL Fiddle

    数据库结构

    https://docs.google.com/open?id=0B9ExyO6ktYcOenZ1WlBwdlY2R3c

    我添加了3个问题作为样本数据,但查询计算所有问题并返回9.这是不可能的。出了点问题。想不通,我错过了什么。

    更新

    我将解释一些表格:

    1. answer_chk_results - 已检查答案表。因此,如果此表中不存在某些答案,则表示未经检查
    2. lesson_questions - 课程< - >问题关联(通过id)表
    3. courses-lessons - 课程< - >课程协会(由id)表
    4. 只有第一个问题似乎并不那么困难:为了解决所有问题,我的计划如下:

      1. 首先,我们需要获取所有课程名单。查询将如下所示:

        SELECT c.id,c.name FROM courses c

      2. 然后从courses-lessons的每个选定课程中获取1.关联表的所有课程(不知道如何继续之前的查询)

      3. 然后,根据lid

      4. 中选定的课程ID(2.列)计算所有问题

2 个答案:

答案 0 :(得分:5)

您可以使用条件计数语句来完成此操作,因此您不需要所有子查询:

SELECT  c.ID,
        c.Name,
        COUNT(DISTINCT q.ID) AS Questions,
        COUNT(DISTINCT CASE WHEN a.ID IS NULL THEN q.ID END) AS UnAnswered,
        COUNT(DISTINCT CASE WHEN cr.ID IS NULL AND a.ID IS NOT NULL THEN q.ID END) AS UnChecked
FROM    Courses c
        LEFT JOIN `Courses-Lessons` cl
            ON cl.CID = c.ID
        LEFT JOIN Lesson_Questions q
            ON cl.ID = q.LID
        LEFT JOIN Answers a
            ON a.QID = q.ID
        LEFT JOIN Answer_chk_results cr
            ON a.ID = cr.AID
GROUP BY c.ID --, c.Name

<强> SQL Fiddle


修改

SELECT  c.ID,
        c.Name,
        COUNT(DISTINCT q.ID) AS Questions,
        COUNT(DISTINCT CASE WHEN a.ID IS NULL THEN q.ID END) AS UnAnswered,
        COUNT(a.ID) AS Answers,
        COUNT(DISTINCT CASE WHEN cr.ID IS NULL THEN a.ID END) AS UnChecked
FROM    Courses c
        LEFT JOIN `Courses-Lessons` cl
            ON cl.CID = c.ID
        LEFT JOIN Lesson_Questions q
            ON cl.LID = q.LID
        LEFT JOIN Answers a
            ON a.QID = q.QID
        LEFT JOIN Answer_chk_results cr
            ON a.ID = cr.AID
GROUP BY c.ID, c.Name

答案 1 :(得分:3)

也许 - http://sqlfiddle.com/#!2/d23b4/42

SELECT  c.ID,
        c.Name,
        COUNT(q.ID) AS 'Questions',
        SUM(CASE WHEN a.ID IS NOT NULL Then 1 ELSE 0 END ) as 'Unanswered',
        SUM(CASE WHEN cr.ID IS NOT NULL Then 1 ELSE 0 END ) as 'Unchecked'
FROM    Courses c
        LEFT JOIN `Courses-Lessons` cl
            ON cl.CID = c.ID
        LEFT JOIN Lesson_Questions q
            ON cl.ID = q.LID
        LEFT JOIN Answers a         
            ON a.QID = q.ID             
        LEFT JOIN Answer_chk_results cr
            ON a.ID = cr.AID
GROUP BY c.ID