Sql server 成对重复、相同的行。只更新其中一个
在SQL Server中处理相当大的表。表中有一些相同的行。我需要删除重复的行。问题是我无法更改此表,即创建ID列 我可以在成对的重复项上更新另一行的一列值。然后使用此值删除 如何仅更新这些行中的一个? 例如:首次/最后插入、首次出现、最新/最旧 谢谢 表结构Sql server 成对重复、相同的行。只更新其中一个,sql-server,common-table-expression,row-number,Sql Server,Common Table Expression,Row Number,在SQL Server中处理相当大的表。表中有一些相同的行。我需要删除重复的行。问题是我无法更改此表,即创建ID列 我可以在成对的重复项上更新另一行的一列值。然后使用此值删除 如何仅更新这些行中的一个? 例如:首次/最后插入、首次出现、最新/最旧 谢谢 表结构 NrValue | Comment | Value1 | Value2 | Value3 | --------|-----------|-----------|-----------|------------
NrValue | Comment | Value1 | Value2 | Value3 |
--------|-----------|-----------|-----------|---------------|
00000 | data0 | zz | top | vivalasvegas|
00100 | NULL | N/A | sex | no |
00100 | NULL | N/A | sex | no |
00200 | NULL | female | sex | yes |
00200 | NULL | female | sex | yes |
00300 | NULL | male | sex | yesplease |
00300 | NULL | male | sex | yesplease |
00400 | data21 | M | -- | na |
00500 | NULL | F | ezig | na |
所以,我可以使用“注释”列进行更新,但除了重复的行之外,我不能触摸其他行。我通过NrValue
知道哪些行可以更新。
结果将是:
NrValue | Comment | Value1 | Value2 | Value3 |
--------|-----------|-----------|-----------|---------------|
00000 | data0 | zz | top | vivalasvegas|
00100 | 1 | N/A | sex | no |
00100 | 2 | N/A | sex | no |
00200 | 3 | female | sex | yes |
00200 | 4 | female | sex | yes |
00300 | 5 | male | sex | yesplease |
00300 | 6 | male | sex | yesplease |
00400 | data21 | M | -- | na |
00500 | NULL | F | ezig | na |
最后,我删除了NrValue
=00100、00200或00300和Comment
=2、4或6的行
ROW_NUMBER() OVER(PARTITION BY AllRelevantColumns ORDER BY SomeOrderCriteria)
这将为所有行生成1
,但重复的行将获得2
(或3
…)
您可以将此值放置在新列中,或将其用于清理
更新以下测试数据。。。
这个概念称为可更新的CTE。从编号…
中删除将实际影响基础表
如果
NrValue
不足以检测到重复的行,只需通过向分区添加更多列即可。您不需要更新,您希望删除重复的行,那么为什么要执行中间步骤
您的代码应该如下所示:
declare @t table (col1 int, col2 int);
insert into @t values
(1, 1), (1, 1),
(1, 2), (1, 2),(1, 2), (1, 2),
(3, 2), (3, 2),(3, 2);
with cte as
(
select *, row_number() over (partition by col1, col2 order by 1/0) rn
from @t
)
delete cte
where rn > 1;
select *
from @t;
很抱歉没有在评论中发布(行数限制和代码格式丢失)您可以使用CTE一次性对记录进行编号和删除。如果没有数据和表格结构,我认为无法给出准确的答案。没有表格结构或数据,因此这个问题对其他人不会有很大帮助。但是我同意你的答案+1。也许我可以:更新BigTable Set Comment=ROW_NUMBER()(按注释分区),其中NrValue在('0001000'、'0002000'、'0003000')
中,或者我应该:更新BigTable Set Comment=ROW_NUMBER()(按注释分区)中,除注释外的所有列('0001000'、'0002000'、'0003000')
@Kaptah,正如Tim Biegeleisen告诉你的那样,已经没有足够的信息让我们给出更好的答案。请尝试研究一下CTE
,可更新的CTE
和行数
…出于某种原因,我得到Msg 102,级别15,状态1,第12行附近的语法不正确])“.
这是最后一个括号。很好的例子,+1来自我这边,但是1/0
看起来太-嗯-禁止了。。。我更喜欢orderby(选择NULL)
更新的问题,添加了表结构它对于数字来说太长了,而且1/0可以:)但是如果它看起来不好,就不要像@Shnugo的答案那样按getdate()排序:出于某种原因,我得到了msg102,level15,state1,第12行“')附近的语法不正确。
这是最后一个括号。
declare @t table (col1 int, col2 int);
insert into @t values
(1, 1), (1, 1),
(1, 2), (1, 2),(1, 2), (1, 2),
(3, 2), (3, 2),(3, 2);
with cte as
(
select *, row_number() over (partition by col1, col2 order by 1/0) rn
from @t
)
delete cte
where rn > 1;
select *
from @t;