如何删除一个表中的重复行并将另一个表中的引用更新为剩余行?复制仅发生在名称中。 Id列是标识列。
假设我们有两个表Doubles
和Data
。
Doubles table (
Id int,
Name varchar(50)
)
Data Table (
Id int,
DoublesId int
)
现在我在Doubls表中有两个条目:
Id Name
1 Foo
2 Foo
数据表中有两个条目:
ID DoublesId
1 1
2 2
最后,双打表中只应有一个条目:
Id Name
1 Foo
数据表中有两个条目:
Id DoublesId
1 1
2 1
在双打表中,每个名称(最多30个)和常规“单个”行可以有任意数量的重复行。
答案 0 :(得分:8)
我没有运行这个,但希望它应该是正确的,并且足够接近最终的解决方案才能到达那里。如果你愿意,请告诉我任何错误,我会更新答案。
--updates the data table to the min ids for each name
update Data
set id = final_id
from
Data
join
Doubles
on Doubles.id = Data.id
join
(
select
name
min(id) as final_id
from Doubles
group by name
) min_ids
on min_ids.name = Doubles.name
--deletes redundant ids from the Doubles table
delete
from Doubles
where id not in
(
select
min(id) as final_id
from Doubles
group by name
)
答案 1 :(得分:0)
注意:我已经冒昧地将您的Id重命名为DoubleID和DataID。我发现与他人一起工作。
DECLARE @Doubles TABLE (DoubleID INT, Name VARCHAR(50))
DECLARE @Data TABLE (DataID INT, DoubleID INT)
INSERT INTO @Doubles VALUES (1, 'Foo')
INSERT INTO @Doubles VALUES (2, 'Foo')
INSERT INTO @Doubles VALUES (3, 'Bar')
INSERT INTO @Doubles VALUES (4, 'Bar')
INSERT INTO @Data VALUES (1, 1)
INSERT INTO @Data VALUES (1, 2)
INSERT INTO @Data VALUES (1, 3)
INSERT INTO @Data VALUES (1, 4)
SELECT * FROM @Doubles
SELECT * FROM @Data
UPDATE @Data
SET DoubleID = MinDoubleID
FROM @Data dt
INNER JOIN @Doubles db ON db.DoubleID = dt.DoubleID
INNER JOIN (
SELECT db.Name, MinDoubleID = MIN(db.DoubleID)
FROM @Doubles db
GROUP BY db.Name
) dbmin ON dbmin.Name = db.Name
/* Kudos to quassnoi */
;WITH q AS (
SELECT Name, ROW_NUMBER() OVER (PARTITION BY Name ORDER BY Name) AS rn
FROM @Doubles
)
DELETE
FROM q
WHERE rn > 1
SELECT * FROM @Doubles
SELECT * FROM @Data
答案 2 :(得分:0)
看看这个,我试过这个,工作正常
--create table Doubles ( Id int, Name varchar(50))
--create table Data( Id int, DoublesId int)
--select * from doubles
--select * from data
Declare @NonDuplicateID int
Declare @NonDuplicateName varchar(max)
DECLARE @sqlQuery nvarchar(max)
DECLARE DeleteDuplicate CURSOR FOR
SELECT Max(id),name AS SingleID FROM Doubles
GROUP BY [NAME]
OPEN DeleteDuplicate
FETCH NEXT FROM DeleteDuplicate INTO @NonDuplicateID, @NonDuplicateName
--Fetch next record
WHILE @@FETCH_STATUS = 0
BEGIN
--select b.ID , b.DoublesID, a.[name],a.id asdasd
--from doubles a inner join data b
--on
--a.ID=b.DoublesID
--where b.DoublesID<>@NonDuplicateID
--and a.[name]=@NonDuplicateName
print '---------------------------------------------';
select
@sqlQuery =
'update b
set b.DoublesID=' + cast(@NonDuplicateID as varchar(50)) + '
from
doubles a
inner join
data b
on
a.ID=b.DoublesID
where b.DoublesID<>' + cast(@NonDuplicateID as varchar(50)) +
' and a.[name]=''' + cast(@NonDuplicateName as varchar(max)) +'''';
print @sqlQuery
exec sp_executeSQL @sqlQuery
print '---------------------------------------------';
-- now move the cursor
FETCH NEXT FROM DeleteDuplicate INTO @NonDuplicateID ,@NonDuplicateName
END
CLOSE DeleteDuplicate --Close cursor
DEALLOCATE DeleteDuplicate --Deallocate cursor
---- Delete duplicate rows from original table
DELETE
FROM doubles
WHERE ID NOT IN
(
SELECT MAX(ID)
FROM doubles
GROUP BY [NAME]
)
请尝试让我知道这是否有助于你
由于
~Aamod
答案 3 :(得分:0)
如果您正在使用MYSQL,以下对我有用。我做了两步
步骤1->
update Data
join
Doubles
on Data.DoublesId = Doubles.id
join
(
select name, min(id) as final_id
from Doubles
group by name
) min_ids
on min_ids.name = Doubles.name
set DoublesId = min_ids.final_id;
第2步->
DELETE c1 FROM Doubles c1
INNER JOIN Doubles c2
WHERE
c1.id > c2.id AND
c1.name = c2.name;