版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_24309787/article/details/84976762
在SQL Server数据库查询中,为了对查询结果进行对比、分析,我们经常会用到GROUP BY子句以及COUNT()函数来对查询结果进行分类、统计等。但是我们在使用的过程中往往会存在一些问题,就是当有where条件时,被where条件过滤的数据不显示了,所以count()函数等于0 的结果并没有显示。
现在有一张表sc的数据如下(sno学生编号,cno课程编号,score分数):
我想要统计各科及格的数量,理想的结果应该如下:
cno | num |
---|---|
c001 | 4 |
c002 | 3 |
c003 | 0 |
由此问题,我们很容易写出如下语句:
SELECT
cno,
count(score) num
FROM
sc
WHERE
score > 60
GROUP BY
cno
可运行之后得到的结果如下:
cno | num |
---|---|
c001 | 4 |
c002 | 3 |
没有cno=c003,num=0的记录。
二、原因分析:
造成以上结果的原因是因为在SELECT语句中WHERE子句先于GROUP BY执行,因此在执行GROUP BY子句时,表中的记录已经将 cno=c003 的记录过滤,分组处理中自然不会计算在内。
SQL SELECT语句完整的执行顺序:
1、FROM子句组装来自不同数据源的数据;
2、WHERE子句基于指定的条件对记录进行筛选;
3、GROUP BY子句将数据划分为多个分组;
4、使用聚集函数进行计算;
5、使用HAVING子句筛选分组;
6、计算所有表达式;
7、使用ORDER BY对结果进行排序。
三、解决方案:
构造含有所有CategoeyID的结果集与其上语句所得结果集进行连接,并利用NULL替换函数(如MySql中的IFNULL()函数)将NULL替换为0。
示例语句如下:
SELECT DISTINCT
sc.cno,
IFNULL(t.num, 0) num
FROM
sc
LEFT JOIN (
SELECT
cno,
count(score) num
FROM
sc
WHERE
score > 60
GROUP BY
cno
) t ON sc.cno = t.cno
执行之后即可得到想要的结果。