求一个过滤数据的SQL

rover11 2014-10-14 11:18:03
由于错误操作,造成 A表中一部分数据重复(除了主键ID外,其他字段都相同),现在需要重复的数据只保留一笔
还有一个情况是 A表的主键和B表有外键关联 (A.id = B.fid), 那会有3种情况

1. A表重复数据 都 在B表中有关联-> 删除A.id较大的一个
2. A表重复数据 在B表中都没有关联-> 删除A.id较大的一个
3.A表重复数据 有一笔 在B表中有关联-> 删除A表中没有关联的哪一个


以上
感谢
...全文
119 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
gw6328 2014-10-14
  • 打赏
  • 举报
回复


DECLARE @a TABLE(id INT,c1 VARCHAR(10))

INSERT INTO @a SELECT 1,'a' UNION ALL 
SELECT 2,'a' UNION ALL 
SELECT 3,'a' UNION ALL 
SELECT 4,'b' UNION ALL 
SELECT 5,'b' UNION ALL
SELECT 6,'c' UNION ALL 
SELECT 7,'c';

DECLARE @b TABLE(fid int)
INSERT INTO @b(fid) VALUES(2),(4),(5);

DELETE FROM @a WHERE id NOT IN (
	SELECT MIN(id) AS id FROM  @a WHERE id IN (SELECT fid FROM @b)
	GROUP BY c1
	UNION ALL 
		SELECT MIN(id) FROM @a a WHERE NOT EXISTS(SELECT 1 FROM @a x WHERE a.c1=x.c1 AND x.id IN (SELECT fid FROM @b))
		GROUP BY a.c1
	);
SELECT * FROM @a;

/*
id          c1
----------- ----------
2           a
4           b
6           c
*/
rover11 2014-10-14
  • 打赏
  • 举报
回复
引用 4 楼 alimake 的回复:
1. A表重复数据 都 在B表中有关联-> 删除A.id较大的一个 2. A表重复数据 在B表中都没有关联-> 删除A.id较大的一个 3.A表重复数据 有一笔 在B表中有关联-> 删除A表中没有关联的哪一个 看你这个描叙,相同的记录最多只有2条吗?
恩,就2条
rover11 2014-10-14
  • 打赏
  • 举报
回复
A: id name address 1 zs aaa 2 zs aaa //重复 3 sm bbb //重复,在B表中无关联 4 sm bbb 5 lr ccc 6 lr ccc //重复,在B表中无关联 7 ms ddd 8 xd eee B: id fid other 1 1 yyy //情况1 2 2 yyy //情况1 3 4 zzz //情况3 4 7 uuu 需要过滤的A表数据为 2,3,6 B表不管
xiaodongni 2014-10-14
  • 打赏
  • 举报
回复
1. A表重复数据 都 在B表中有关联-> 删除A.id较大的一个 2. A表重复数据 在B表中都没有关联-> 删除A.id较大的一个 3.A表重复数据 有一笔 在B表中有关联-> 删除A表中没有关联的哪一个 看你这个描叙,相同的记录最多只有2条吗?
rover11 2014-10-14
  • 打赏
  • 举报
回复
引用 2 楼 wmxcn2000 的回复:
1. A表重复数据 都 在B表中有关联-> 删除A.id较大的一个 表B 中的数据,怎么处理?
B表不管
卖水果的net 版主 2014-10-14
  • 打赏
  • 举报
回复
1. A表重复数据 都 在B表中有关联-> 删除A.id较大的一个 表B 中的数据,怎么处理?
xiaodongni 2014-10-14
  • 打赏
  • 举报
回复
贴点数据出来。 好写点
rover11 2014-10-14
  • 打赏
  • 举报
回复
非常感谢7,8楼的支持,整理好了: ) PS:8楼的答案删除的是ID较小的一个, 不知是否是受排序影响? 不过功能实现了 再次感谢2位高人
xiaodongni 2014-10-14
  • 打赏
  • 举报
回复

 
  begin tran
  delete a 
  where id not in  (select id from 
  (select a.id,b.fid as id1 , name,a.address ,ROW_NUMBER()over(PARTITION by name,address order by 
   b.fid desc ,a.id desc ) as n from a left join b on a.id=b.fid) as t
   where n=1 )
     select * from a
id          name address
----------- ---- -------
2           zs   aaa
4           sm   bbb
6           lr   ccc
7           ms   ddd
8           xd   eee

(5 行受影响)


--结果

  

34,590

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧