Oracle SQL中关联其他表时如何使用SELECT DISTINCT去重?
Oracle SQL关联表去重:实现单工单唯一记录
问题背景
作为SQL初学者,仅有数据库只读权限,需要查询WRK表中状态为PA的工单信息,需包含以下字段:
- 工单编号
WO - 创建人
WRK.PERSON(每个工单的创建人固定) - 来自STR表
CREATED列的工单创建日期
执行初始关联SQL后,返回超300万条完全重复的工单记录,期望每个工单仅返回一条唯一记录。
初始执行的SQL代码
Select WRK.WO, WRK.PERSON, STR.CREATED FROM WRK JOIN STR on WRK.WO = STR.WO WHERE WRK.STATE = 'PA'
当前查询结果(存在大量重复记录)
| WO | Person | Created |
|---|---|---|
| 280 | W123 | 20220101 |
| 280 | W123 | 20220101 |
| 280 | W123 | 20220101 |
| 280 | W123 | 20220101 |
| 299 | E201 | 20200531 |
| 299 | E201 | 20200531 |
| 299 | E201 | 20200531 |
| 300 | R360 | 20221115 |
| 300 | R360 | 20221115 |
| 300 | R360 | 20221115 |
期望查询结果(每个工单仅一条记录)
| WO | Person | Created |
|---|---|---|
| 280 | W123 | 20220101 |
| 299 | E201 | 20200531 |
| 300 | R360 | 20221115 |
解决方法
问题根源在于STR表中同一WO对应多条重复的CREATED记录,直接关联会导致WRK表的单条工单被多次匹配。最终采用先对STR表分组去重,再关联WRK表的方案,同时添加Oracle优化提示提升大数量级查询的性能:
Select /*+ full(wrk) parallel(8) USE_HASH(wrk str) */ WRK.WO, WRK.PERSON, STR.CREATED FROM WRK JOIN (SELECT /*+ NO_MERGE */ wo, MAX(created) created FROM str GROUP BY wo) STR on WRK.WO = STR.WO WHERE WRK.STATE = 'PA'
方案说明
- 子查询中对STR表按
WO分组,通过MAX(created)获取每个工单唯一的创建日期(因每个工单创建日期固定,用MIN也可),先完成STR表的去重 - 将去重后的STR结果集与WRK表关联,避免了重复匹配
- 添加的Oracle优化提示:
full(wrk):强制对WRK表进行全表扫描parallel(8):启用8并行度加速查询USE_HASH(wrk str):指定使用哈希连接提升关联效率NO_MERGE:阻止优化器将子查询与主查询合并,保证先执行子查询的分组去重
内容的提问来源于stack exchange,提问作者smurfit
相关产品推荐
相关产品推荐

