这是场景:我的表中有重复的行,具有相同的ID,Name等。
1)我必须找到匹配所有条件的重复行(已完成)
2)仅在条件匹配时删除它们
3)使用已删除记录的ID并更新表中的现有行
为此,我创建了一个2临时表。 Temp1是包含所有记录的表。 Temp2由重复的行组成。
00799d60 <sub_799d60>:
799d60: b573 push {r0, r1, r4, r5, r6, lr}
799d62: 0004 movs r4, r0
799d64: f000 e854 blx 799e10 <jmp_sub_100C54>
799d68: 4b15 ldr r3, [pc, #84] ; (799dc0 <sub_799d60+0x60>)
799d6a: 0005 movs r5, r0
799d6c: 4668 mov r0, sp
799d6e: 4798 blx r3
您可以在下面看到查询不应删除突出显示的最后两列,因为该部分不匹配。它应该只从Temp1和Temp2中删除匹配的条件。
方案2:删除Temp1中的重复记录,并使用键将Section和Classcode的数据更新为NULL。这就是我期望的突出显示为NULL的情况。
您可以自己运行此查询-只需复制并粘贴。
答案 0 :(得分:1)
是的,对于场景1,将删除行,因为问题出在本节中。
I added this table for references.
添加了此#temp2表以供以后使用。
CREATE Table #Temp2 (
Id int,
Name Varchar(64),
StudentNo INT NULL,
ClassCode Varchar(8) NULL,
Section Varchar(8) NULL,
)
IF OBJECT_ID('tempdb..#tmp4') IS NOT NULL
DROP TABLE #tmp4
select t1.Id,t1.Name,t1.StudentNo,t1.Section,t1.ClassCode,
Duplicate_RowNumber
INTO #Duplicatedata
from CTE as c INNER JOIN #Temp1 as t1 ON t1.Id = c.Id
and t1.StudentNo = t1.StudentNo
and c.Duplicate_RowNumber >1
select * from #Duplicatedata
这将同时满足两个条件,因为#temp 1将同时具有Elle的两行,因为您的加入条件仅针对ID和学生号。
为清楚起见,我添加了行号列。
Id Name StudentNo Section ClassCode Duplicate_RowNumber
1 Joe 123 I A1 2
1 Joe 123 I A1 2
2 Harry 113 H X2 2
2 Harry 113 H X2 2
3 Elle 121 E1 J1 2
3 Elle 121 E J1 2
由于您的分区基于学生编号和ID,因此每个重复的行将具有2个或更多的行号。
您可以使用此方法删除。
select
ROW_NUMBER() over (partition by Id
, StudentNo
order by Id, StudentNo, section)as Duplicate_RowNumber
, * into #tmp4 from #Temp1
--You can add section in your order as well for consistency purpose.
delete
from #tmp4
output deleted.id, deleted.Name, deleted.StudentNo, deleted.ClassCode,
deleted.Section into #Temp2
where Duplicate_RowNumber > 1
之后,您似乎想要在最终表中保留一行,而将另一行放入已删除的表中。对于Elle,由于分区不是基于section的,因此它将删除Final表中的一行并仅保留一行。
要确保从最终表中删除1行,可以使用此行。
DELETE t
OUTPUT deleted.Id , deleted.Name ,deleted.StudentNo ,deleted.ClassCode
,deleted.Section into @inserted FROM
(select *, row_number() over (Partition by tm.name, tm.studentNo Order by ID,
StudentNo, section ) rownum from #temp1 tm) t
join #Temp2 t2 on t.Id = t2.Id
and t.Name = t2.Name
and t.StudentNo = t2.StudentNo
and t.ClassCode = t2.ClassCode
and t.Section = t2.Section
where t.rownum > 1
如果您注意到我添加了此行号,那么它将不会从最终表中删除两行,因为Joe和Harry具有所有匹配的属性,并且它将删除两行。
select * from @inserted
Output you get:
Id Name StudentNo ClassCode Section
3 Elle 121 J1 E1
2 Harry 113 X2 H
1 Joe 123 A1 I
最后,您可以通过这种方式更新决赛桌。 #方案2
update TMP
SET ClassCode = NULL, SECTION = NULL
FROM
#Temp1 TMP
JOIN @INSERTED I ON TMP.Id = I.Id
AND TMP.StudentNo = I.StudentNo
SELECT * FROM #Temp1
最终输出:
Id Name StudentNo ClassCode Section
1 Joe 123 NULL NULL
2 Harry 113 NULL NULL
3 Elle 121 NULL NULL
8 Jane 191 A1 E
5 Silva 811 S1 SE
6 Juan 411 S2 SE
7 Carla 431 S2 SE
请注意,我已添加脚本并仅针对需要更改的部分输出,其余部分与您提供的脚本相同。