MySQL-SQL聚合(多行)函数-count()

介绍

用于统计查询结果集中的行数。可以根据不同的参数,统计 满足条件 的 记录数量 或 非 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;

性能优化

  1. 优先使用 COUNT(*) 而非 COUNT(1) 或 COUNT(主键):

    • 在 MySQL 中,COUNT(*)、COUNT(1) 和 COUNT(主键) 性能几乎相同
    • 但 COUNT(*) 语义更清晰,表示统计所有行
  2. 避免使用 COUNT(*) 与 WHERE 条件:

    • 如果只需要满足特定条件的行数,确保相关列有索引
    • 例如:WHERE department = '技术部',确保 department 列有索引
  3. 对于大型表的计数:

    • 考虑使用近似计数方法,如 EXPLAIN 或数据库元数据
    • 或者定期将计数结果缓存到另一个表中

总结

  1. COUNT(*) 统计所有行数,性能最优,是最常用的形式。
  2. COUNT(列名) 只统计该列非 NULL 的值,适合需要排除 NULL 值的场景。
  3. COUNT(DISTINCT 列名) 统计唯一值数量,适合去重统计,但性能相对较低。
  4. 选择合适的 COUNT() 形式可以显著提高查询性能,特别是在处理大型数据集时。

原文出处:/show_1GW2Ji3VjTYN.html