4. 使用DISTINCT统计不重复部门列表

使用DISTINCT统计不重复部门列表 学习卡片

任务说明

员工表 employees 中同一部门会出现多次(每个员工一行)。本节要回答两个问题:一是如何用 DISTINCT 取出所有不重复的部门名称;二是验证 DISTINCT 与 GROUP BY 在“去重结果”上是否一致。示例使用如下表结构与数据(教学示例数据,非真实业务数据):

CREATE TABLE employees (
  emp_id     INT PRIMARY KEY,
  emp_name   VARCHAR(20),
  department VARCHAR(20),
  salary     DECIMAL(8,2),
  hire_date  DATE
);

INSERT INTO employees VALUES
(1,'张伟','研发部',18000,'2020-03-01'),
(2,'李娜','研发部',16500,'2021-07-15'),
(3,'王强','市场部',12000,'2019-11-20'),
(4,'赵敏','市场部',13500,'2022-01-05'),
(5,'陈杰','财务部',11000,'2020-09-10'),
(6,'刘洋','研发部',21000,'2018-05-22'),
(7,'孙丽','人事部', 9500,'2021-02-18'),
(8,'周涛','市场部',12800,'2023-04-01'),
(9,'吴静','财务部',10500,'2022-08-30'),
(10,'郑凯','人事部', 9800,'2023-06-12');

DISTINCT 去重写法

DISTINCT 作用于 SELECT 的结果集,对整行组合去重。单列去重时,它等价于“把该列所有出现过的值各保留一次”。

SELECT DISTINCT department
FROM employees
ORDER BY department;

预期结果(5 个不重复部门,按名称排序):

department
人事部
市场部
研发部
财务部

注意:上表按数据库默认排序规则展示,实际顺序取决于 ORDER BY 与字符集排序规则;若使用中文排序,结果顺序可能不同,但“不重复部门集合”本身不变。

GROUP BY 去重写法

用 GROUP BY 把相同部门归为一组,每组只输出一行,同样得到不重复部门列表:

SELECT department
FROM employees
GROUP BY department
ORDER BY department;

一致性验证

要证明两种写法结果一致,不能只看“看起来一样”,而应做集合层面的比较。下面用 EXCEPT 双向差集验证:若两个方向都返回 0 行,则两个结果集完全相同。

-- 方向一:DISTINCT 有而 GROUP BY 没有的部门
SELECT DISTINCT department FROM employees
EXCEPT
SELECT department FROM employees GROUP BY department;

-- 方向二:GROUP BY 有而 DISTINCT 没有的部门
SELECT department FROM employees GROUP BY department
EXCEPT
SELECT DISTINCT department FROM employees;

两个查询都返回空结果集,说明 DISTINCT department 与 GROUP BY department 在本例数据上去重结果一致。若某数据库不支持 EXCEPT,可改用 NOT IN 或 LEFT JOIN ... IS NULL 做等价验证。

关键区别:DISTINCT 只做去重,不能直接对分组做聚合;GROUP BY 是分组机制,分组后可以配合 COUNT、AVG、HAVING 等做统计与过滤。仅当“只取不重复值”时,两者结果一致。

易错点:SELECT DISTINCT department, salary 去重的是“部门+薪资”整行组合,不是只对部门去重。若只想按部门去重,SELECT 列表中不要混入其他列。

DISTINCT 与 GROUP BY 去重一致性验证 employees 表 emp_id emp_name department salary hire_date 10 行员工记录 部门列有重复值 研发部×3 市场部×3 财务部×2 人事部×2 DISTINCT 路径 SELECT DISTINCT department 对结果集整行去重 GROUP BY 路径 SELECT department GROUP BY department 按部门分组,每组一行 去重结果集 人事部 市场部 研发部 财务部 4 个不重复部门 EXCEPT 双向差集 两个方向均返回 0 行 → 结果集完全一致

结果判读与验证要点

  • 行数判读:去重结果应为 4 行(人事部、市场部、研发部、财务部)。若返回 10 行,说明 DISTINCT 未生效或写成了 SELECT department。
  • 一致性判读:两个 EXCEPT 查询都返回空集,才可判定两种写法结果一致;任一方向有行,说明结果集存在差异。
  • 排序影响:ORDER BY 只影响展示顺序,不影响去重集合;验证一致性时不要依赖默认顺序。
  • NULL 处理:若部门列存在 NULL,DISTINCT 与 GROUP BY 都会把 NULL 视为一个独立分组值,结果仍一致,但需在业务上确认是否要排除 NULL。