介绍
用于统计查询结果集中的行数。可以根据不同的参数,统计 满足条件 的 记录数量 或 非 NULL 值的数量。
使用方法
COUNT() 函数有几种不同的使用方式,其行为和性能各不相同
COUNT(*) 或 count(1)
- 统计 所有行 的数量,包括包含
NULL值的行 - MySQL 会尽可能优化,通常使用最快的索引(如主键索引或覆盖索引)来计数
查询员工总数
select count(*) from emp
或者
select count(1) from emp
COUNT(列名)
- 统计该列中非 NULL 值的数量
- 如果列名是主键,性能接近
COUNT(*) - 如果列名可以为 NULL,则需要逐行检查值是否为 NULL
查询有奖金的人数
select count(comm) from emp
推荐写法
下面写法,初级开发工程师 可能会忘记 不统计 null 值
select count(comm) from emp
所以一般我们编写sql要明确,不要引起歧义,推荐写法如下:
select count(*) from emp where comm>0
COUNT(DISTINCT 列名)
- 统计该列中唯一的非 NULL 值的数量
- 需要额外的去重操作,性能相对较差
查询有多少个工作种类
select count(distinct job) from emp
搭配查询条件
查询工资大于1600(含1600),有多少人
select count(*) from emp where 1600<=sal
案例
-- 创建示例表
CREATE TABLE employees (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
department VARCHAR(50),
salary DECIMAL(10, 2),
hire_date DATE
);
-- 插入示例数据
INSERT INTO employees (name, department, salary, hire_date) VALUES
('张三', '技术部', 8000.00, '2020-01-15'),
('李四', '市场部', 6500.00, '2021-03-20'),
('王五', '技术部', 9000.00, '2019-11-05'),
('赵六', '财务部', NULL, '2022-05-10'),
('孙七', '市场部', 7500.00, NULL);
1. 统计表的总行数
-- 统计所有员工数量
SELECT COUNT(*) FROM employees; -- 返回 5
-- 统计技术部员工数量
SELECT COUNT(*) FROM employees WHERE department = '技术部'; -- 返回 2
2. 统计非 NULL 值
-- 统计有薪资记录的员工数量(排除 salary 为 NULL 的行)
SELECT COUNT(salary) FROM employees; -- 返回 4
-- 统计有入职日期的员工数量
SELECT COUNT(hire_date) FROM employees; -- 返回 4
3. 统计唯一值
-- 统计有多少个不同的部门
SELECT COUNT(DISTINCT department) FROM employees; -- 返回 3
-- 统计每个部门的员工数量
SELECT department, COUNT(*)
FROM employees
GROUP BY department;
4. 结合 JOIN 使用
-- 假设还有 departments 表
CREATE TABLE departments (
dept_id INT PRIMARY KEY,
dept_name VARCHAR(50)
);
-- 统计每个部门的员工数量(包括没有员工的部门)
SELECT d.dept_name, COUNT(e.id) AS employee_count
FROM departments d
LEFT JOIN employees e ON d.dept_name = e.department
GROUP BY d.dept_name;
性能优化
优先使用
COUNT(*)而非COUNT(1)或COUNT(主键):- 在 MySQL 中,
COUNT(*)、COUNT(1)和COUNT(主键)性能几乎相同 - 但
COUNT(*)语义更清晰,表示统计所有行
- 在 MySQL 中,
避免使用
COUNT(*)与WHERE条件:- 如果只需要满足特定条件的行数,确保相关列有索引
- 例如:
WHERE department = '技术部',确保department列有索引
对于大型表的计数:
- 考虑使用近似计数方法,如
EXPLAIN或数据库元数据 - 或者定期将计数结果缓存到另一个表中
- 考虑使用近似计数方法,如
总结
COUNT(*)统计所有行数,性能最优,是最常用的形式。COUNT(列名)只统计该列非 NULL 的值,适合需要排除 NULL 值的场景。COUNT(DISTINCT 列名)统计唯一值数量,适合去重统计,但性能相对较低。- 选择合适的
COUNT()形式可以显著提高查询性能,特别是在处理大型数据集时。