MySQL查询返回意外值

时间:2012-08-30 12:01:12

标签: mysql sql database

需要生成课程列表并计算

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

    我的数据库结构看起来像那样

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

    一些表的解释:

    1. answer_chk_results - 已检查答案表。因此,如果此表中不存在某些答案,则表示未经检查
    2. lesson_questions - 课程< - >问题关联(通过id)表
    3. courses-lessons - 课程< - >课程协会(由id)表
    4. 执行

          SELECT
          c.ID,
          c. NAME,
          COUNT(lq.id) AS Questions,
          COUNT(
              CASE
              WHEN a.id IS NULL THEN
                  lq.id
              END
          ) AS UnAnswered,
          COUNT(
              CASE
              WHEN cr.id IS NULL THEN
                  lq.id
              END
          ) AS UnChecked
      FROM
          courses c
      LEFT JOIN `courses-lessons` cl ON cl.cid = c.id
      LEFT JOIN `lesson_questions` lq ON lq.lid = cl.lid
      LEFT JOIN answers a ON a.qid = lq.qid
      LEFT JOIN answer_chk_results cr ON cr.aid = a.id
      GROUP BY
          c.ID
      

      首先在SQL fiddle上使用示例数据对其进行测试。 (真实数据很大,所以我不能把它放在sqlfiddle上)它返回了一些值。思想效果很好。但是当我用真实数据测试它时,看到它返回错误的值。外汇,当我手动计数时,all questions count的结果必须是25,但它返回27.也许我做错了。

      注意在我的本地计算机上运行的MySQL服务器,如果您想远程连接到我的桌面并使用真实数据测试查询,我可以为您提供teamviewer ID和密码。

2 个答案:

答案 0 :(得分:1)

我怀疑问题是不同的连接会导致行的倍增。解决此问题的最佳方法是使用每个维度的子查询。以下是一种更实用的方法。用COUNT DISTINCT替换select中的COUNT:

SELECT c.ID, c. NAME,
       COUNT(distinct lq.id) AS Questions,
       COUNT(distinct CASE WHEN a.id IS NULL THEN lq.id END) AS UnAnswered,
       COUNT(distinct CASE WHEN cr.id IS NULL THEN lq.id END) AS UnChecked

与COUNT相比,COUNT DISTINCT是一种资源匮乏(它必须删除重复项)。但是,它可能适用于您的目的。

答案 1 :(得分:0)

使用此查询

SELECT
    c.ID,
    c.NAME,
    COUNT(lq.id) AS Questions,
    COUNT(IFNULL(a.id),lq.id)AS UnAnswered,
    COUNT(IFNULL(cr.id),lq.id)AS UnChecked,
FROM    courses c
LEFT JOIN `courses-lessons` cl ON cl.cid = c.id
LEFT JOIN `lesson_questions` AS lq ON lq.lid = cl.lid
LEFT JOIN answers a ON a.qid = lq.qid
LEFT JOIN answer_chk_results cr ON cr.aid = a.id
GROUP BY c.ID