【问题标题】:Delete duplicate data and load into another table in SQL Server删除重复数据并加载到 SQL Server 中的另一个表中
【发布时间】:2015-12-23 03:03:21
【问题描述】:

我有一个关于 SQL Server 的问题。

表:emp

empid   |  name |sal
1       |  abc  |100
2       |  def  |200
3       |  test |300
2       |  har  |500
3       |  jai  |600
4       | kali  |240

此表有重复数据基于上表我想从emp表中删除重复数据

并且应该将重复的数据加载到empduplicate 表中。

这里empid 是独一无二的。如果empid 出现多次,则该记录被视为重复。

empduplicate 结构如下:

Empid   |  name  | sal

最后删除重复数据后,我希望看到emp表中的数据如下所示:

empid  |  name  | sal 
1      |  abc   | 100
4      | kali   | 240

为了删除重复项,我尝试了以下代码:

;with duplicate as 
(
    select 
        *,
        row_number()over (partition by empid order by empid) as rn
    from emp
)
delete from duplicate 
where rn > 1

但我无法删除整个记录。

示例:empid=2 有重复数据

empid|name |sal
2    |def  |200
2    |har  |500

我需要删除整个empid=2 对应的记录。 empid=2 有重复项,需要将其从emp 表中删除。

而empduplicate表需要加载重复数据如下:

empid    | name   |sal
2        |def     |200
2        |har     |500
3        |test    |300
3        |jai     |600

为了插入重复数据,我尝试了以下代码:

insert into empduplicate 
    select 
        id, name, sal 
    from 
         emp  
    group by 
         id 
    having 
         count(*) > 1

该查询引发错误:

选择列表中的列“duplicate.name”无效,因为它既不包含在聚合函数中,也不包含在 GROUP BY 子句中。

请告诉我如何编写查询来实现我在 SQL Server 中的任务

【问题讨论】:

    标签: sql-server sql-server-2008


    【解决方案1】:

    你快到了。不要使用ROW_NUMBER,而是使用COUNT:

    WITH CteInsert AS(
        SELECT *,
            cnt = COUNT(empid) OVER(PARTITION BY empid)
        FROM emp
    )
    INSERT INTO empduplicate(empid, name, sal)
    SELECT
        empid, name, sal
    FROM CteInsert
    WHERE cnt > 1;
    
    WITH CteDelete AS(
        SELECT *,
            cnt = COUNT(empid) OVER(PARTITION BY empid)
        FROM emp
    )
    DELETE FROM CteDelete WHERE cnt > 1;
    

    您需要先执行INSERT,然后再执行DELETE。此外,您可能希望将其包含在单个事务中。

    【讨论】:

      【解决方案2】:
      SELECT DISTINCT * INTO #tmp FROM emp
       DELETE FROM emp
      INSERT INTO emp
      SELECT * FROM #tmp DROP table #tmp
      
      SELECT * FROM emp ---------------------------- All Distinct ID
      
      SELECT * INTO #tmp FROM emp
      WHERE empid in(
          SELECT empid FROM emp 
          group by empid having count(*) = 1
      )
      DELETE FROM emp
      INSERT INTO emp
      SELECT * FROM #tmp DROP table #tmp
      
      SELECT * FROM emp ----------------------------All ID which is not duplicate
      
      INSERT INTO empduplicate  
        SELECT * FROM emp where empid in(
          SELECT empid FROM emp 
          group by empid having count(*) >1
      )
      
      SELECT * FROM empduplicate  -------------------ALL Duplicate value.
      

      【讨论】:

        【解决方案3】:
        BEGIN TRAN
        SELECT * INTO empduplicate FROM
        (
         SELECT * 
         FROM emp
         WHERE empid IN (
          SELECT empid FROM emp 
          GROUP BY empid
          HAVING COUNT(empid)>1
         )
        ) as M
        
        DELETE FROM emp WHERE empid IN (
         SELECT empid FROM emp
         GROUP BY empid
         HAVING COUNT(empid)>1
        )
        
        COMMIT TRAN
        

        【讨论】:

          猜你喜欢
          • 2017-05-20
          • 2013-07-17
          • 2022-01-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-04-05
          • 1970-01-01
          • 2016-08-29
          相关资源
          最近更新 更多