sql查询数据,可能会有重复的数据,那就要用到去重复的方法了,下面讲讲几种去重复的方法。
一、使用DISTINCT关键字
用法很简单,在sql中 select 后面添加 DISTINCT 即可。
但是有一个问题,使用DISTINCT会针对查询体中的全部字段进行去重复,只有全部字段都相同,才会被去重复。
sql改写后,才能达到去重复的效果
二、使用ROW_NUMBER() OVER(PARTITION BY 字段1 ORDER BY 字段2 DESC) rows=1方式
表示根据字段1分组,在分组内部根据字段2排序,而此函数计算的值就表示每组内部排序后的顺序编号(组内连续的唯一的)。
具体用法为:
根据trainee_id分组,再根据id排序
取rownum=1的数据,rownum为热名称,外面再包裹一层查询
该种方式可适用于单个字段重复,且有其他字段辅助排序的情况
三、使用group by方式去重复
对重复的字段group by,其他查询字段,使用聚合函数包裹,比如max()
该方式适用于单个字段重复,且其他字段使用聚合函数取值影响不大的情形
四、使用临时表关联查询去重复
该方式适用于复杂重复条件去重复情况
下列以一个例子演示
简单描述一下关系:
1、trainee_rotation_program为轮换计划表,其中有两种类型的数据,一种plan_type为2的个人计划,一种plan_type为1或者null的轮换计划 个人计划类型的数据的trainee_id(实习生id)有值;轮换计划的数据,trainee_id没有值,但是可以通过group_id(轮换分组id)关联trainee_info(实习生档案表) 获取trainee_id ,并且一个group_id可能对应多个trainee_id。
2、同一个时间段内,一个实习生可能既存在个人计划,又存在轮换计划。此时需要取个人计划数据,过滤掉轮换计划数据。
3、下列红框中的查询表示,在当前时间里,这个trainee_id为70的实习生存在两条数据,一条儿科的轮换计划数据,一条神经内科八病室的个人计划数据,最终查询出来的数据中,只需要显示神经内科八病室的数据。
4、红框中的trainee_id是根据group_id关联实习生表查询出来的全部trainee_id拼接字符串。再用实习生档案表,关联红框sql查询返回的结果。红框中的查询返回数据,也使用到了方式二的去重复方法。tt.rows=1 这是为了处理分组中只有一个实习生id的去重复情况。
5、将整个查询数据生成一个临时表TEMP,对temp表按照id分组,并获得每个分组的trainee_id数量,此处是为了获得哪些id的数据是有重复的。再关联temp本身,使用case when,将有重复数据的(count计数大于1的)取个人计划数据显示。其中count=0表示没有计划数据的实习生,count=1表示有轮换计划或者个人计划数据的实习生。最终查询的数据id=70的李英只有一条数据
WITH temp as ( select a.*,tt.trainee_id,tt.dept_name,tt.dept_id FROM trainee_info a left join ( SELECT Row_Number() OVER (partition by trainee_id order by d1,plan_type desc ) rows,* from ( select dept_id,(case when p.trainee_id is null then (stuff((SELECT ',' + CAST(i.id as varchar(4)) FROM trainee_info i WHERE i.group_id=p.group_id FOR XML path('')), 1, 1, '')) else p.trainee_id end) trainee_id, p.dept_name,p.starttime,p.endtime,p.group_id,datediff(day,p.starttime,GETDATE()) as d1,p.plan_type from trainee_rotation_program p where datediff(day,p.starttime,GETDATE()) >= 0 and datediff(day,p.endtime,GETDATE()) <= 0 ) t ) tt on (a.id in (select * from Fun_SplitStr(tt.trainee_id,','))) and tt.rows=1 ) select t2.* from temp t2,(select t1.id,count(t1.trainee_id) as count1 from temp t1 group by t1.id) t3 where t2.id=t3.id and 1=(case when t3.count1>1 and cast(t2.id as varchar) =cast(t2.trainee_id as varchar) then 1 when t3.count1=0 then 1 when t3.count1=1 then 1 else 0 end)
还没有评论,来说两句吧...