给定的是从给定表中删除重复项的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
答案 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