Oracle的count()函数
讲解 Oracle 的 count 函数在统计行数、非空值、去重数量和分组过滤场景中的用法,并说明 count(*)、count(列) 与 count(distinct) 的差异。
Oracle 的 count()函数用于统计行数或表达式的非空数量,是 SQL 查询中最常见的聚合函数之一。它看似简单,但在 count(*)、count(列名)、count(distinct 列名) 和分组统计之间,存在一些容易混淆的差异。
count(*) 统计结果集行数
count(*) 表示统计查询结果集中有多少行,不关心某一列是否为空。只要该行满足 where 条件,就会被计入结果。
SELECT COUNT(*)
FROM orders
WHERE status = 'PAID';这类写法常用于统计订单数、用户数、日志条数等。对于是否使用索引、是否全表扫描,需要结合过滤条件、统计信息和执行计划判断,不能简单认为 count(*) 一定快或一定慢。
count(列名) 统计非空值
count(column_name) 统计的是该列不为 NULL 的行数。如果某行满足查询条件,但指定列为空,则不会计入统计。
SELECT COUNT(email)
FROM users;这条语句统计的是 email 不为空的用户数量,而不是用户总数。数据质量检查中经常利用这个特性判断字段填充率,例如用 count(email) / count(*) 估算某字段的非空比例。
count(distinct) 统计去重数量
count(distinct column_name) 用于统计去重后的非空值数量。它适合计算独立用户数、不同品类数、不同状态数等指标。
SELECT COUNT(DISTINCT user_id)
FROM access_log
WHERE log_date >= DATE '2026-01-01';去重统计通常比普通 count 更消耗资源,数据量较大时要关注排序、哈希聚合和临时表空间使用情况。如果是高频指标,可能需要通过汇总表、分区或近似统计能力优化。
与 group by、having 配合
count 常与 group by 配合,用于按维度统计数量;再通过 having 过滤聚合结果。
SELECT dept_id, COUNT(*) AS employee_count
FROM employee
GROUP BY dept_id
HAVING COUNT(*) > 10;需要注意,where 在分组前过滤明细行,having 在分组后过滤聚合结果。把条件放错位置,会导致结果不符合预期或查询性能下降。
使用时的常见误区
第一,不要把 count(列名) 当成总行数,它会排除空值。第二,统计业务指标时要先明确口径,例如“注册用户数”是否包含注销用户,是否按创建时间过滤。第三,count 只是 SQL 层的统计函数,结果是否可信还取决于数据清洗、去重规则和时间范围。
掌握 Oracle 的 count()函数,重点不在记住语法,而在理解统计对象。只有明确统计的是行、非空值还是去重值,才能写出稳定、可解释的 SQL。


