码迷,mamicode.com
首页 > 其他好文 > 详细

删除多字段的重复行保留最大最小行

时间:2015-12-07 12:16:56      阅读:132      评论:0      收藏:0      [点我收藏+]

标签:

  有张表格之前没有设计关键字段的唯一约束,导致有时候执行插入操作时不小心执行了多次就出现了重复记录,后面重新加入唯一约束,由于已经有了重复记录,无法添加,需要先删除重复记录。

        看了网上的一些删除重复记录的方法(好像都是转载于同一篇文章,至少看了十几篇都是同样的内容),其中一个链接:http://blog.csdn.net/anya/article/details/6407280

        自己现在是需要建立多字段唯一约束(非主键),用文中的方法是不行的,反正在SQL Server 2012中是无法通过的。改写了下,如下:

1、查询重复记录:

[sql] view plaincopy技术分享技术分享
 
  1. SELECT * FROM dbo.Table T  
  2. WHERE EXISTS (SELECT 字段1, 字段2, 字段3 FROM dbo.TableSign WHERE 字段1= T.字段1 AND 字段2= T.字段2  
  3. AND 字段3 = T.字段3 GROUP BY 字段1, 字段2, 字段3 HAVING COUNT(*) > 1)  
  4. AND T.SelfID NOT IN (SELECT MIN(SelfID) FROM dbo.Table GROUP BY 字段1, 字段2, 字段3 HAVING COUNT(*) > 1)  
  5.   
  6. 其中:字段1, 字段2, 字段3指需要建立唯一约束的三个字段,SelfID指表Table中的一个自增字段。  

 

 

2、删除重复记录,只保留SelfID最小的记录,也就是第一次插入的记录:

[sql] view plaincopy技术分享技术分享
 
    1. DELETE FROM dbo.TableSign  
    2. WHERE SelfID IN  
    3.   
    4. (SELECT SelfID FROM dbo.Table T  
    5.   
    6. WHERE EXISTS (SELECT 字段1, 字段2, 字段3 FROM dbo.TableSign WHERE 字段1= T.字段1 AND 字段2= T.字段2  
    7. AND 字段3 = T.字段3 GROUP BY 字段1, 字段2, 字段3 HAVING COUNT(*) > 1)  
    8. AND T.SelfID NOT IN (SELECT MIN(SelfID) FROM dbo.Table GROUP BY 字段1, 字段2, 字段3 HAVING COUNT(*) > 1))

 

 

SQL中的联接类型可以分为如下几种:

1)内联接   仅显示两个联接表中的匹配行的联接。

2)外联接   甚至包括在联接表中没有相关行的行的联接。可以创建外联接的三个变化形式来指定所包括的不匹配行:

    • 2-1)左向外联接
    • 2-2)右向外联接 
    • 2-3)完整外部联接 
    • 3)交叉联接 
      其中值得补充的是自联接
    • 4)自联接

表可以通过自联接与自身联接。例如,可以使用自联接 查 找一张表 使用相同Email的用户。

现在students表数据如下:

Stuid       Sname      semail 
----------- ---------- -------------------------------------------------- 
1           张飞         zhangfei@sanguo.com 
2           刘备         liubei@sanguo.com 
3           关羽         guanyu@sanguo.com 
4           赵云         zhaoyun@sanguo.com 
5           赵小云        zhaoyun@sanguo.com

如何找出具有相同email的用户姓名呢?

由于此查询涉及 students表与其自身的联接,因此 students表以两种角色显示。若要区分这两个角色,必须在 FROM 子句中为 students表提供两个不同的别名(st1 和 st2)。这些别名用来限定其余查询中的列名。

select st1.sname,st2.sname,st1.semail 
from students st1   inner join students st2 
on st1.stuid=st2.stuid 
where st1.semail=st2.semail

以下是结果集:

sname      sname      semail 
---------- ---------- -------------------------------------------------- 
张飞         张飞         zhangfei@sanguo.com 
刘备         刘备         liubei@sanguo.com 
关羽         关羽         guanyu@sanguo.com 
赵云         赵云         zhaoyun@sanguo.com 
赵小云        赵小云        zhaoyun@sanguo.com

(5 行受影响)

若要消除完全相同的行,那么必须要这样

select st1.sname,st2.sname,st1.semail 
from students st1   inner join students st2 
on st1.stuid<>st2.stuid  --注意这里的不等号 
where st1.semail=st2.semail

以下是结果集:

sname      sname      semail 
---------- ---------- -------------------------------------------------- 
赵小云        赵云         zhaoyun@sanguo.com 
赵云         赵小云        zhaoyun@sanguo.com

(2 行受影响)

若要消除结果中用户姓名完全顺序颠倒相同的行(顺序颠倒) 
select st1.sname,st2.sname,st1.semail 
from students st1   inner join students st2 
on st1.stuid>st2.stuid 
where st1.semail=st2.semail

以下是结果集:

sname      sname      semail 
---------- ---------- -------------------------------------------------- 
赵小云        赵云         zhaoyun@sanguo.com

(1 行受影响)

        这样就达到目标了
        -----------------------------------------------------------------------------------------------
        一个表与自身进行连接,称为自连接


        问题的提出:一个网友提出这样一个SQL题目,说自己想了很久没解决,我一看,这不是很简单吗

        可是自己在查询分析器调试了半天原来问题并不是那不简单



        有一个学生表,里面有 学号 功课编号

        学生成绩三个字段.用一个SQL查询语句得出每门功课成绩最好的前两名


        学号  功课编号     学生成绩

         1          1             99

         2          1             98

         3          1             100

         4          2             88

         5          2             87

         6          2             88

         7          3             99

         8          3             88

         9          3             100


        解决方法

        SELECT DISTINCT 学生表1.*

        FROM 学生表 学生表1 INNER JOIN

              学生表 学生表2 ON 学生表1.学号 IN

                  (SELECT TOP 2 学生表.学号

                 FROM 学生表

                 WHERE 学生表.功课编号 = 学生表1.功课编号

                 ORDER BY 学生成绩 DESC)


        查询结果

        学号  功课编号     学生成绩

         1          1             99

         2          1             98

         4          2             88

         6          2             88

         7          3             99

         9          3             100

删除多字段的重复行保留最大最小行

标签:

原文地址:http://www.cnblogs.com/chengjun/p/5025603.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!