SQL Server - 如何使部分重复的行从原始行继承值

Posted

技术标签:

【中文标题】SQL Server - 如何使部分重复的行从原始行继承值【英文标题】:SQL Server - How to make partially duplicate rows inherit values from original row 【发布时间】:2018-08-14 23:52:16 【问题描述】:

为了跨数据集链接记录,我首先根据关键链接变量(按名称、出生日期、性别等进行分区并删除 row_number > 1 的位置)将记录删除为不重复的记录。链接完成后,我留下了一个新变量“unique_id”,但这只会归因于原始记录(因为我删除了部分重复项)。我现在想将此“unique_id”重新附加到所有部分重复项。我怎么能这样做呢?有没有更好的方法我可以从一开始就使用?

数据目前如下所示:

row_number unique_id id      first_name last_name activity_date
1          10        2       Davy       Jones     1726-11-25
2          --        12      Davy       Jones     1751-02-11
3          --        43      Davy       Jones     1811-06-15
1          100       12114   John       Smith     2018-06-01
2          --        123123  John       Smith     2022-07-05
1          90        2591    Mary       Sue       2013-05-18

我希望“unique_id”像这样继承原件:

row_number unique_id id      first_name last_name activity_date
1          10        2       Davy       Jones     1726-11-25
2          10        12      Davy       Jones     1751-02-11
3          10        43      Davy       Jones     1811-06-15
1          100       12114   John       Smith     2018-06-01
2          100       123123  John       Smith     2022-07-05
1          90        2591    Mary       Sue       2013-05-18

生成此表的代码如下:

create table #test (
    unique_id int,
    id int,
    first_name varchar(255),
    last_name varchar(255),
    activity_date date
)

insert into #test 
values (100, 12114, 'John', 'Smith', '2018-06-01')

insert into #test (id, first_name, last_name, activity_date)
values (123123, 'John', 'Smith', '2022-07-05')

insert into #test
values (90, 2591, 'Mary', 'Sue', '2013-05-18')

insert into #test
values (10, 2, 'Davy', 'Jones', '1726-11-25')

insert into #test (id, first_name, last_name, activity_date)
values (12, 'Davy', 'Jones', '1751-02-11')

insert into #test (id, first_name, last_name, activity_date)
values (43, 'Davy', 'Jones', '1811-06-15')

select 
row_number() over (partition by first_name, last_name order by first_name, last_name) as row_number
,unique_id, id, first_name, last_name, activity_date
from #test

【问题讨论】:

【参考方案1】:

一种简单的方法——假设每个 first_name/last_name 对有一个值——是使用窗口函数:

select t.*, max(unique_id) over (partition by first_name, last_name) as new_unique_id
from #test t;

这可以放入update:

with toupdate as (
      select t.*, max(unique_id) over (partition by first_name, last_name) as new_unique_id
      from #test t
     )
update toupdate
    set unique_id = new_unique_id;

这是一个rextester 说明语法。

【讨论】:

这是什么版本的 SQL? @Alex 。 . .这是 SQL Server 语法——即问题上的标记。 @Alex 。 . .我更新了错误的字段,但代码有效。我添加了一个 rextester,这样你就可以看到语法工作了。 只是为了帮助我理解-您不需要像 Alex 的回答那样在更新语句之后指定 FROM #test ... INNER JOIN Dups,因为您已经在 WITH 函数中指定了 FROM #test 并且您是直接从这里更新(而 Alex 从 #test 更新而不是最初创建的 WITH 函数)? @Maharero 。 . .我的回答使用可更新的 CTE。它引用了一张表,因此不需要join【参考方案2】:

试试这个:

with Dups as(
    select 
    row_number() over (partition by first_name, last_name order by first_name, last_name) as dup_number,
    -- dense_rank() over (order by first_name, last_name) as DuplicateGroupNumber, -- this allows you to see groups
    max(unique_id) over (partition by first_name, last_name) as GroupUniqueID,
    unique_id, id, first_name, last_name, activity_date
    from #test
)
update a
set unique_id = GroupUniqueID
from #test as a
    inner join Dups as b on a.id = b.id

select * from #test

结果

unique_id   id          first_name  
----------- ----------- ------------
100         12114       John        
100         123123      John        
90          2591        Mary        
10          2           Davy        
10          12          Davy        
10          43          Davy        

【讨论】:

【参考方案3】:

看起来您应该使用您认为合适的任何字段将具有链接 id 的记录的子集与没有链接 id 的记录连接起来,然后从链接中的 id 更新未链接集中的 id设置。

【讨论】:

以上是关于SQL Server - 如何使部分重复的行从原始行继承值的主要内容,如果未能解决你的问题,请参考以下文章

如何从MS SQL Server 2012中的不同表中减去连续的行?

如何获取 SQL SERVER 数据库中所有表的行数 [重复]

sql server"已更新或删除的行值要么不能使该行成为唯一行,要么改变了多个行" 解决方案

SQL Server - 将条件链接到原始行的 SUM 前面的行

如何在SQL Server中选择特定日期的行,忽略时间。

如何在 SQL Server 触发器中复制插入、更新、删除的行