oracle 去重并按时间排序取第一条
select t.* from (select a.*, row_number() over(partition by 需要分组的字段 order by 更新时间 desc) rw from 表 a) t where t.rw = 1
row_number()over(partition by col1 order by col2)表示根据col1分组,在分组内部根据col2排序,而此函数计算的值就表示每组内部排序后的顺序编号(组内连续的唯一的)。
与rownum的区别在于:使用rownum进行排序的时候是先对结果集加入伪劣rownum然后再进行排序,而此函数在包含排序从句后是先排序再计算行号码。
row_number()和rownum差不多,功能更强一点(可以在各个分组内从1开始排序)。
rank()是跳跃排序,有两个第二名时接下来就是第四名(同样是在各个分组内)
dense_rank()也是连续排序,有两个第二名时仍然跟着第三名。相比之下row_number是没有重复值的。
oracle 分析函数 row_number(),返回一个整数值(>=1);
例子1:
有个需求是营销客户活动表中activityId和cifNo是唯一索引,但是表中索引创建错误,导致表中存在很多activityId和cifNo重复的记录,而且两条重复记录中有一条的VISIT_TIMES是大于1的,我们现在要做的是,删除这个营销客户活动表中重复的记录,删除VISIT_TIMES等于0的那条,怎么做?
--根据activity_id、cif_no分组,分组内根据visit_times倒序,找出所有记录
select *, row_number() over(PARTITION by ACTIVITY_ID, CIF_NO order by VISIT_TIMES DESC) RN from MKT_ACTIVITY_CIF_5
--找出按activityId、cif_no分组后,重复的记录
select * from (
select *, row_number() over(PARTITION by ACTIVITY_ID, CIF_NO order by VISIT_TIMES DESC) RN from MKT_ACTIVITY_CIF_5
) t WHERE t.RN > 1
select ACTIVITY_CIF_ID from (
select *, row_number() over(PARTITION by ACTIVITY_ID, CIF_NO order by VISIT_TIMES DESC) RN from MKT_ACTIVITY_CIF_5
) t WHERE t.RN > 1
--根据ACTIVITY_CIF_ID删除重复的记录
delete from MKT_ACTIVITY_CIF_5 where ACTIVITY_CIF_ID in (
select ACTIVITY_CIF_ID from (
select *, row_number() over(PARTITION by ACTIVITY_ID, CIF_NO order by VISIT_TIMES DESC) RN from MKT_ACTIVITY_CIF_5
) t WHERE t.RN > 1
删除完成后验证是否还有重复记录,期望:无记录
select activity_id, cif_no from MKT_ACTIVITY_CIF_5 group by ACTIVITY_ID , CIF_NO HAVING count(*) > 1
浙公网安备 33010602011771号