解析SQL查询逻辑:如何返回dummy表的唯一值?
解析这段Oracle去重SQL的工作原理
先补全表结构&明确查询效果
你给出的建表语句漏了表名,正确的写法是:
create table dummy ( srno number, name varchar2(250) );
这段SQL的核心作用是给dummy表去重,保留每组重复数据(srno+name完全相同的记录)里,rowid最小的那一条——Oracle里的rowid是数据插入时生成的唯一标识符,不会变更,越小代表这条数据插入时间越早,所以本质是保留每组重复数据里最早插入的那条。
用示例拆解逻辑
假设你的dummy表有以下测试数据(rowid用模拟值方便理解,实际是Oracle内部生成的字符串):
| srno | name | 模拟rowid |
|---|---|---|
| 1 | 张三 | R1 |
| 1 | 张三 | R2 |
| 2 | 李四 | R3 |
| 3 | 王五 | R4 |
| 3 | 王五 | R5 |
| 3 | 王五 | R6 |
1. 子查询的作用
外层查询遍历dummy表的每一条记录(记为a),子查询针对当前a记录做两件事:
- 只筛选和
a的srno、name完全相同的记录(也就是同一重复组的记录) - 统计这些记录里,
rowid小于等于a.rowid的数量
2. 逐行验证条件
- 拿
srno=1、name=张三、rowid=R1的记录来说:
子查询统计同一组里rowid<=R1的记录,只有它自己,count结果是1,满足1=1的条件,会被保留。 - 拿
srno=1、name=张三、rowid=R2的记录来说:
子查询统计同一组里rowid<=R2的记录,有R1和R2两条,count结果是2,不满足1=2,会被排除。 - 王五的三条记录同理:
只有rowid=R4的那条,子查询count结果是1,会被保留;R5对应的count是2,R6对应的count是3,都被排除。 - 李四只有一条记录,子查询count结果是1,直接保留。
3. 最终输出结果
执行完这段SQL后,得到的就是去重后的结果:
| srno | name |
|---|---|
| 1 | 张三 |
| 2 | 李四 |
| 3 | 王五 |
一句话总结
这段SQL靠rowid的唯一性和顺序性,通过关联子查询统计每组重复数据中当前记录的"前置+自身"数量,只留数量为1的那条——也就是每组重复数据的第一条,实现去重。
内容的提问来源于stack exchange,提问作者shayaaz
相关产品推荐
相关产品推荐

