一:
让我们先看一下BOL里面对count(*)以及count(col)的说明:
COUNT(*) 返回组中的项数。包括 NULL 值和重复项。
COUNT(ALL expression) 对组中的每一行都计算 expression 并返回非空值的数量。
expression: 除 text、image 或 ntext 以外任何类型的表达式。不允许使用聚合函数和子查询。
- :指定应该计算所有行以返回表中行的总数。
COUNT(*) 不需要任何参数,而且不能与 DISTINCT 一起使用。
COUNT(*) 不需要 expression 参数,因为根据定义,该函数不使用有关任何特定列的信息。
COUNT(*) 返回指定表中行数而不删除副本。它对各行分别计数。包括包含空值的行。
也就是说count()只是返回表中行数,因此SQL Server在处理count()的时候只需要找到属于表的数据块块头,然后计算一下行数就行了,而不用去读取里面数据列的数据。
而对于count(col)就不一样了,为了去除col列中包含的NULL行,SQL Server必须读取该col的每一行的值,然后确认下是否为NULL,然后在进行计数。因此count(*)应该是比count(col)快的。
即
count(0)=count(1)=count(*)
-
count(指定的有效值)–执行计划都会转化为count(*)
-
如果指定的是列名,会判断是否有null,null不计算
二:
按每天统计同一列中不同种类的数量占总数的比例
1.该列只有两种类型或统计不为空的情况下占比总数。
–过去7天每天有车牌号的机动车数据占机动车数据总数的比例
Select
COUNT(cph) AS ycp ,
COUNT(1) AS total ,
CONCAT( ROUND( COUNT(cph)/COUNT(1)*100 ,3 ),'%') AS rate ,
dt
FROM table1
WHERE dt between ‘20181208’ and ‘20181214’
GROUP BY dt;
2.该列有多种数据类型时,可以使用 case when来过滤
Select
COUNT( case when cph=1 then 1 end) AS type1 , --或者用SUM()
CONCAT( ROUND( COUNT( case when cph=1 then 1 end) /COUNT(1)*100 ,3 ),'%')
COUNT( case when cph=2 then 2 end) AS type2 ,
……
COUNT( case when cph=3 then 3 end) AS type3 ,
……
dt
FROM table1
WHERE dt between ‘20181208’ and ‘20181214’
GROUP BY dt;
其中,concat()是拼接函数,Round(number,N)是保留N位小数点函数