sql server数据去重复的四种方法

原创  郑建华   2020-02-09   102人阅读  0 条评论
摘要:

sql查询数据,可能会有重复的数据,那就要用到去重复的方法了,下面讲讲几种去重复的方法。一、使用DISTINCT关键字用法很简单,在sql中  select 后面添加 DISTINCT 即可。但是有一个问题,使用DISTINCT会针对查询体中的全部字段进行去重复,只有全部字段都相同,才会被去重复。sql改写后,才能达到去重复的效果二、使用ROW_NUMBER() OVER(PARTITION BY 字段1 ORDER BY 字段2 DESC)  rows=1方式表示根据字段1

sql查询数据,可能会有重复的数据,那就要用到去重复的方法了,下面讲讲几种去重复的方法。

一、使用DISTINCT关键字

用法很简单,在sql中  select 后面添加 DISTINCT 即可。

但是有一个问题,使用DISTINCT会针对查询体中的全部字段进行去重复,只有全部字段都相同,才会被去重复。

image.png

sql改写后,才能达到去重复的效果

image.png

二、使用ROW_NUMBER() OVER(PARTITION BY 字段1 ORDER BY 字段2 DESC)  rows=1方式

表示根据字段1分组,在分组内部根据字段2排序,而此函数计算的值就表示每组内部排序后的顺序编号(组内连续的唯一的)。

具体用法为:

根据trainee_id分组,再根据id排序

image.png

取rownum=1的数据,rownum为热名称,外面再包裹一层查询

image.png

该种方式可适用于单个字段重复,且有其他字段辅助排序的情况

三、使用group by方式去重复

对重复的字段group by,其他查询字段,使用聚合函数包裹,比如max()

image.png

该方式适用于单个字段重复,且其他字段使用聚合函数取值影响不大的情形

四、使用临时表关联查询去重复

该方式适用于复杂重复条件去重复情况

下列以一个例子演示

简单描述一下关系:

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的去重复情况。image.png

5、将整个查询数据生成一个临时表TEMP,对temp表按照id分组,并获得每个分组的trainee_id数量,此处是为了获得哪些id的数据是有重复的。再关联temp本身,使用case when,将有重复数据的(count计数大于1的)取个人计划数据显示。其中count=0表示没有计划数据的实习生,count=1表示有轮换计划或者个人计划数据的实习生。最终查询的数据id=70的李英只有一条数据

image.png

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)




本文地址:https://www.zjh336.cn/?id=241
版权声明:本文为原创文章,版权归 郑建华 所有,欢迎分享本文,转载请保留出处!

发表评论


表情

还没有留言,还不快点抢沙发?