【问题标题】:Problem constructing where clause to include null/0 values构造 where 子句以包含 null/0 值的问题
【发布时间】:2011-09-25 12:53:29
【问题描述】:

我有一个应用程序,用户可以在其中进行测试(由问题和答案组成)。

我正在尝试构建一个查询,该查询返回按问题分组的答案计数,用于特定教师和测试。 问题是我希望查询对没有答案的问题返回 0 个计数。

答案

  • 身份证
  • question_id
  • test_id
  • student_id

问题

  • 身份证

teacher_students

  • student_id
  • teacher_id

测试

  • 身份证

查询

   SELECT COUNT(answers.id) AS rcount,
          questions.id 
     FROM "questions"
LEFT JOIN answers ON answers.question_id = questions.id
LEFT JOIN teacher_students ON teacher_students.student_id = answers.student_id
    WHERE (questions.test_id = 1)  
      AND (teacher_students.teacher_id = 1)
 GROUP BY questions.id 
 ORDER BY questions.id

输出

 rcount | question_id 
--------+----
      4 | 1
      2 | 3

期望的输出

 rcount | question_id 
--------+----
      4 | 1
      0 | 2
      2 | 3
      0 | 4

如果我删除teacher_students.teacher_id = 1,返回的问题数是正确的,但计数不正确。

【问题讨论】:

    标签: sql postgresql


    【解决方案1】:

    teacher_students.teacher_id = 1 检查从WHERE 子句移至加入ON 子句。

    当引用 LEFT JOIN 右侧表的条件放入 WHERE 子句时,LEFT JOIN 被取消,它充当INNER JOIN

    SELECT count(teacher_students.student_id) AS rcount      <--- changed
         , questions.id 
    FROM "questions"
      LEFT JOIN answers 
        ON answers.question_id = questions.id
      LEFT JOIN teacher_students 
        ON teacher_students.student_id = answers.student_id
        AND teacher_students.teacher_id = 1
    WHERE questions.test_id = 1
    
    GROUP BY questions.id 
    ORDER BY questions.id
    

    【讨论】:

    • 你的回答很好。但在结构上,最好将ON 子句仅用于连接。所以最好这样做:((teacher_students.teacher_id = 1) OR (teacher_students.teacher_id is NULL)) on WHERE 子句。
    • @Karolis:不。如果人们要使用 OUTER JOIN 语法,他们必须意识到WHERE 中的条件与 OUTER JOIN 的 ON 子句中的条件之间存在差异。使用 OUTER JOIN 时,WHERE 子句标准在 之后 应用,而 ON 子句标准在 JOIN 之前应用。您所倡导的可能会导致与预期截然不同的结果集。
    • @Karolis “但在结构上它更好” 你能详细说明一下吗?我从来没有考虑过向连接谓词添加附加条件。这样做的内在结构性问题是什么?
    • @Karolis:是的,我同意,您的建议可能会更好地让以后查看代码的任何人都清楚意图。处理OR 条件并不是 MySQL 优化器的最佳属性。
    • 为了保持指定连接条件的ON子句的纯度,编写它的方法是将对teacher_students的引用更改为对过滤teacher_students的内联视图的引用。计划者将这与将过滤条件放在 ON 子句中一样对待,但恕我直言,它实际上会更清楚地说明语句的含义。但是有些人将任何子查询视为“天哪!邪恶的低效复杂性!”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多