用于删除重复项的SQL查询脚本

时间:2017-10-09 09:48:16

标签: sql sql-server database tsql

给定的是从给定表中删除重复项的sql脚本。 表有三个字段:

id (pk, int identity), imei (varchar), name (varchar), lastconnected (datetime)

此表中的某些记录对name和imei具有相同的值,但id和lastconnected具有不同的值.Mentioned sql脚本删除重复记录,但具有lastconnected的最新值的记录除外。

此处出现的问题是此脚本会删除所有不重复的内容,例如ID为10的条目也会被删除。

如何解决这个问题?

DECLARE @table TABLE
(
  id int, 
  name varchar(10),
  imei varchar(10),
  [date] datetime
)

insert into @table select 1, 'a','a', '2015/01/01' 
insert into @table select 2, 'a','a', '2016/01/01' 
insert into @table select 3, 'a','a', '2017/02/01'
insert into @table select 4, 'b','b', '2017/01/01' 
insert into @table select 5, 'b','b', '2016/01/01' 
insert into @table select 6, 'c','c', '2017/01/03' 
insert into @table select 7, 'c','c', '2016/01/01' 
insert into @table select 8, 'd','d', '2017/05/05' 
insert into @table select 9, 'd','d', '2016/01/01' 
insert into @table select 10, 'e','e', '2016/01/01'

WHILE (exists (select IMEI, COUNT(IMEI) from @table group by IMEI having    COUNT(IMEI) > 1))  
BEGIN  
 delete from @table where [date]  in (
 select min([date]) from @table group by imei , name having count(*) > 1)   
End 

select * from @table

4 个答案:

答案 0 :(得分:1)

检查一下:

DECLARE @table TABLE
(
  id int, 
  name varchar(10),
  imei varchar(10),
  [date] datetime
)

insert into @table select 1, 'a','a', '2015/01/01' 
insert into @table select 2, 'a','a', '2016/01/01' 
insert into @table select 3, 'a','a', '2017/02/01'
insert into @table select 4, 'b','b', '2017/01/01' 
insert into @table select 5, 'b','b', '2016/01/01' 
insert into @table select 6, 'c','c', '2017/01/03' 
insert into @table select 7, 'c','c', '2016/01/01' 
insert into @table select 8, 'd','d', '2017/05/05' 
insert into @table select 9, 'd','d', '2016/01/01' 
insert into @table select 10, 'e','e', '2016/01/01'

;WITH cte AS(
  select *, ROW_NUMBER() OVER (PARTITION BY imei ORDER BY date DESC) rn
    from @table
)
DELETE FROM cte
  WHERE rn > 1

SELECT * FROM @table

答案 1 :(得分:0)

简单EXISTS方式:

delete from tablename t1
where exists (select 1 from tablename t2
              where t2.imei = t1.imei 
                and t2.name = t1.name
                and t2.lastconnected > t1.lastconnected )

如果存在具有相同imei和名称但后来最后连接的另一行,则删除一行。

答案 2 :(得分:0)

使用公用表表达式(CTE)和ROW_Number函数

可以轻松实现
;WITH cteDups
AS(
    SELECT
          T.name
        , T.imei
        , T.date
        , RN = ROW_NUMBER()OVER(PARTITION BY T.name, T.imei ORDER BY T.date DESC)
    FROM @table T
)
--SELECT * FROM cteDups D WHERE D.RN > 1
DELETE FROM cteDups WHERE RN > 1

答案 3 :(得分:0)

您有一个主键,因此查询可以非常简单,而无需使用CTE:

DECLARE @table TABLE
(
  id int, 
  name varchar(10),
  imei varchar(10),
  [date] datetime
)

insert into @table select 1, 'a','a', '2015/01/01' 
insert into @table select 2, 'a','a', '2016/01/01' 
insert into @table select 3, 'a','a', '2017/02/01'
insert into @table select 4, 'b','b', '2017/01/01' 
insert into @table select 5, 'b','b', '2016/01/01' 
insert into @table select 6, 'c','c', '2017/01/03' 
insert into @table select 7, 'c','c', '2016/01/01' 
insert into @table select 8, 'd','d', '2017/05/05' 
insert into @table select 9, 'd','d', '2016/01/01' 
insert into @table select 10, 'e','e', '2016/01/01'

DELETE t1
FROM @table t
    JOIN @table t1 ON t1.name = t.name AND t1.imei = t.imei
WHERE t1.id < t.id

SELECT * FROM @table