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 去重逻辑示意 enrollments(7行) student_id course_id 1 101 1 101 ←重复 1 102 2 101 2 101 ←重复 2 103 3 101 DISTINCT 按指定列去重 结果(5行) student_id course_id 1 101 1 102 2 101 2 103 3 101 重复行被合并为一行 (2,101)两条不同日期记录 因只查student_id+course_id 故合并为一条

关键要点

  • DISTINCT作用于SELECT后所有列的组合,而非单列;若查询多列,只有当所有指定列的值都相同时才视为重复。
  • DISTINCT会忽略NULL值——多个NULL在去重时被视为相同值,只保留一个。
  • 若需对单列去重但保留其他列信息,DISTINCT无法满足,应改用GROUP BY或窗口函数。
  • COUNT(DISTINCT col)可统计去重后的数量,常用于报表统计。