【Java-后端-Mybatis】DISTINCT 作用

假设我们有两张表:users (用户信息表) 和 user_projects (用户参与的项目表)。

表1: users

┌─────────┬──────┐

│ user_id │ name │

├─────────┼──────┤

│ 1 │ 张三 │

│ 2 │ 李四 │

└─────────┴──────┘

表2: user_projects

注意,这里为用户'张三'(user_id=1)添加了两条完全相同的'项目A'记录。

┌─────────┬──────────────┐

│ user_id │ project_name │

├─────────┼──────────────┤

│ 1 │ 项目A │

│ 1 │ 项目B │

└─────────┴──────────────┘

| 1 | 项目A | <-- 重复记录

| 2 | 项目C |


  1. 不使用 DISTINCT 的查询

如果我们想查询用户'张三'(user_id=1)参与了哪些项目,查询语句如下:

复制代码
1 SELECT
2     u.user_id,
3     u.name,
4     p.project_name
5 FROM
6     users u
7 JOIN
8     user_projects p ON u.user_id = p.user_id
9 WHERE
10     u.user_id = 1;

查询结果 会有3行,因为'张三'在 user_projects 表中有3条记录:

┌─────────┬──────┬──────────────┐

│ user_id │ name │ project_name │

├─────────┼──────┼──────────────┤

│ 1 │ 张三 │ 项目A │

│ 1 │ 张三 │ 项目B │

└─────────┴──────┴──────────────┘

| 1 | 张三 | 项目A | <-- 重复的行


  1. 使用 DISTINCT 的查询

现在,我们在 SELECT 后面加上 DISTINCT:

复制代码
1 SELECT DISTINCT
2     u.user_id,
3     u.name,
4     p.project_name
5 FROM
6     users u
7 JOIN
8     user_projects p ON u.user_id = p.user_id
9 WHERE
10     u.user_id = 1;

DISTINCT 会检查每一行所有列的组合 (user_id, name, project_name) 是否唯一。

  • 第一行 (1, '张三', '项目A') 是唯一的。
  • 第二行 (1, '张三', '项目B') 是唯一的。
  • 第三行 (1, '张三', '项目A') 和第一行完全相同,因此它会被 DISTINCT 关键字移除。

最终查询结果 只有2行:

┌─────────┬──────┬──────────────┐

│ user_id │ name │ project_name │

├─────────┼──────┼──────────────┤

│ 1 │ 张三 │ 项目A │

│ 1 │ 张三 │ 项目B │

└─────────┴──────┴──────────────┘

结论

这个例子清晰地表明,DISTINCT 并不是只看某一列(比如 project_name),而是看整行所有列的值组合。只有当多行的所有列的值都完全相同时,DISTINCT 才会将它们视为重复并只保留一行。

DISTINCT 就是为了防止 JOIN 操作后可能出现的、所有选择列都完全相同的重复行,确保最终返回给程序的结果是干净且唯一的。

相关推荐
廿一夏8 小时前
MySql存储引擎与索引
数据库·sql·mysql
lzhdim9 小时前
SQL 入门 15:SQL 事务:从 ACID 到四种常见的并发问题
数据库·sql
瀚高PG实验室10 小时前
瀚高企业版V9.1.1在pg_restore还原备份文件时提示extract函数语法问题
数据库·瀚高数据库
TDengine (老段)10 小时前
TDengine Tag 设计哲学与 Schema 变更机制
大数据·数据库·物联网·时序数据库·iot·tdengine·涛思数据
YOU OU11 小时前
Spring IoC&DI
java·数据库·spring
Muscleheng12 小时前
Navicat连接postgresql时出现‘datlastsysoid does not exist‘报错
数据库·postgresql
罗超驿13 小时前
18.事务的隔离性和隔离级别:MySQL面试高频考点全解析
数据库·mysql·面试
jran-13 小时前
Redis 命令
数据库·redis·缓存
小江的记录本13 小时前
【Java基础】Java 8-21新特性:JDK21 LTS:虚拟线程、模式匹配switch、结构化并发、序列集合(附《思维导图》+《面试高频考点清单》)
java·数据库·python·mysql·spring·面试·maven
June`14 小时前
多线程redis下如何解决aof重写和rdb持久化的数据一致性问题
数据库·redis·缓存