3. 去重查询
任务说明
查询学生选课记录表,去除重复的选课记录,获取所有不重复的选课组合(学生+课程)。
数据准备
CREATE TABLE enrollments (
student_id INT,
course_id INT,
enroll_date DATE
);
INSERT INTO enrollments VALUES
(1, 101, '2024-03-01'),
(1, 101, '2024-03-01'), -- 完全重复
(1, 102, '2024-03-02'),
(2, 101, '2024-03-01'),
(2, 101, '2024-03-05'), -- 日期不同但学生+课程相同
(2, 103, '2024-03-03'),
(3, 101, '2024-03-02');
DISTINCT 去重查询
-- 查询所有不重复的选课组合(学生+课程)
SELECT DISTINCT student_id, course_id
FROM enrollments
ORDER BY student_id, course_id;
预期输出:
student_id | course_id
-----------+----------
1 | 101
1 | 102
2 | 101
2 | 103
3 | 101
原始表中有7条记录,其中(1,101)出现两次完全重复,(2,101)出现两次但日期不同。DISTINCT作用于SELECT后指定的列组合(student_id, course_id),忽略enroll_date字段,因此(2,101)两条不同日期的记录被合并为一条。最终得到5条不重复记录。
DISTINCT 与 COUNT 组合
-- 统计不重复的选课组合数量
SELECT COUNT(DISTINCT student_id, course_id) AS unique_enrollments
FROM enrollments;
预期输出:
unique_enrollments
------------------
5
DISTINCT 单列去重
-- 查询有哪些学生选修了课程(不重复的学生ID)
SELECT DISTINCT student_id
FROM enrollments
ORDER BY student_id;
预期输出:
student_id
----------
1
2
3
验证方式
在MySQL或PostgreSQL中依次执行上述建表、插入和查询语句。对比原始表行数与DISTINCT查询结果行数:原始7行,去重后5行,说明成功消除了重复的选课组合。若将DISTINCT改为普通SELECT,则(1,101)和(2,101)会各自出现两次,无法达到去重目标。
关键要点
- DISTINCT作用于SELECT后所有列的组合,而非单列;若查询多列,只有当所有指定列的值都相同时才视为重复。
- DISTINCT会忽略NULL值——多个NULL在去重时被视为相同值,只保留一个。
- 若需对单列去重但保留其他列信息,DISTINCT无法满足,应改用GROUP BY或窗口函数。
- COUNT(DISTINCT col)可统计去重后的数量,常用于报表统计。