COUNT计算LEFT JOIN上的某些内容并不存在。为什么?

时间:2017-03-28 22:48:44

标签: mysql sql

我遇到了问题。

我有一个名为usersbycourse的表格,显示了这些信息:

+------------+-----------------+--------+-----------+-------+-----------------+-----------------+
| instanceid | shortname       | userid | firstname | logid | lastaccessdelta | modulesfinished |
+------------+-----------------+--------+-----------+-------+-----------------+-----------------+
|          2 | PJU             |     74 | Robin     |   766 |         1662246 |               0 |
|          3 | Fundgest-GRHN1A |     75 | Batman    |   867 |         1576725 |               0 |
|          3 | Fundgest-GRHN1A |     77 | Abigobeu  |  1004 |          610480 |               0 |
+------------+-----------------+--------+-----------+-------+-----------------+-----------------+

和这个SQL:

SELECT
mdl_course.id,
mdl_course.shortname,
COUNT(CASE WHEN usersbycourse.modulesfinished = 1 THEN NULL ELSE 1 END) AS studentcount
FROM mdl_course LEFT JOIN usersbycourse ON mdl_course.id = usersbycourse.instanceid
GROUP BY mdl_course.id;

SQL的结果是:

+----+-----------------+--------------+
| id | shortname       | studentcount |
+----+-----------------+--------------+
|  1 | Unity I         |            1 |
|  2 | PJU             |            1 |
|  3 | Fundgest-GRHN1A |            2 |
|  4 | asdzxc2         |            1 |
+----+-----------------+--------------+

但为什么呢?在内部SQL没有Unity I,也没有asdzxc2。我如何产生这样的结果:

+----+-----------------+--------------+
| id | shortname       | studentcount |
+----+-----------------+--------------+
|  1 | Unity I         |            0 |
|  2 | PJU             |            1 |
|  3 | Fundgest-GRHN1A |            2 |
|  4 | asdzxc2         |            0 |
+----+-----------------+--------------+

编辑:

我想只计算具有modulesfinished = 0

的行

2 个答案:

答案 0 :(得分:3)

您要找的是SUM而不是COUNT,即

SELECT
mdl_course.id,
mdl_course.shortname,
SUM(CASE WHEN usersbycourse.modulesfinished = 0 THEN 1 ELSE 0 END) AS studentcount
FROM mdl_course LEFT JOIN usersbycourse ON mdl_course.id = usersbycourse.instanceid
GROUP BY mdl_course.id;

答案 1 :(得分:0)

问题是因为您使用LEFT JOIN usersbycourse.modulesfinished的某些值为NULL

你需要学习的东西是

  NULL == something 

总是unknown,而不是true,不是false,只是unknown

因此,当您尝试与= 1进行比较时,您的空值会获得ELSE但不会因为它们不是1,因为其余的都是因为。

因此,如果您将条件更改为

COUNT(CASE WHEN usersbycourse.modulesfinished = 0 THEN 1 ELSE NULL)

只有TRUE匹配得到1,FALSEUNKNOW部分得到NULLCOUNT不会计算空值。这就是你想要的。