Oracle 删除表中的重复行并使用另一个表中的值更新行

Posted

技术标签:

【中文标题】Oracle 删除表中的重复行并使用另一个表中的值更新行【英文标题】:Oracle Remove Duplicates and Update Rows in a Table with a Value from Another Table 【发布时间】:2020-07-14 21:13:09 【问题描述】:

在我的 associates 表中,我有 4,978 个人,至少有 1 个重复。

asscssn     | count(*)
---------     --------
123456789      8
987654321      5
234567890      5

一个人的每个副本在 associates 表中都有一个唯一的 id (asscid)。

asscid | asscssn
------  -------
53492    987654321
53365    987654321
53364    987654321
52104    987654321
50185    987654321

我的 case 表有一个与每个 asscid 相关的 case

docketnumber | asscid
-----------    -------
2010JV0000     53492
2010JV1111     53365
2010JV2222     53364
2010JV3333     52104
2010JV4444     50185

我想获取每个有重复项的人,从 associates 表中获取该人的最新 asscid 并更新 case 表。结果将是:

  docketnumber | asscid
    -----------    -------
    2010JV0000     53492
    2010JV1111     53492
    2010JV2222     53492
    2010JV3333     53492
    2010JV4444     53492

【问题讨论】:

【参考方案1】:

如果我理解正确,你想要:

select c.docketnumber, max_asscid
from cases c join
     (select a.*, max(asscid) over (partition by asscssn) as max_asscid
      from associations a
     ) a
     on c.asscid = a.asscid;

这假定“最新的”asscid 是具有最大值的那个。如果您有另一列指定顺序(例如日期),则可以改用first_value()

编辑:

如果你真的想更新数据:

update cases c
    set assc_id = (select max_asscid
                   from (select a.*, max(asscid) over (partition by asscssn) as max_asscid
                         from associations a
                         where asscssn is not null
                        ) a
                   where a.asscid = c.asscid
                  );

【讨论】:

谢谢@gordon linoff 先生。查询有效。我应该把更新声明放在哪里? 脚本运行良好。我确实注意到一件事。我有 33K 条记录,其中 asscssn 为空,它将所有这些记录更改为最大的 asscid。要忽略 asscssn 为空的记录,我是否将 and asscssn is not null 放在 where a.asscid = c.asscid 之后? @belmer01。 . .您可以在set 之后添加where assc_id is not null 那行不通。 asscid 永远不会为空,因为它是主键。只要 asscssn 不为空,我就想在 associates 表中select max_asscid【参考方案2】:

获取最新的asscid后,您可以使用cross join。这是demo。

select
    docketnumber,
    q.asscid
from table2
cross join
(
  select
    max(asscid) as asscid
  from table1
) q

输出:

| docketnumber | asscid |
| ------------ | ------ |
| 2010JV0000   | 53492  |
| 2010JV1111   | 53492  |
| 2010JV2222   | 53492  |
| 2010JV3333   | 53492  |
| 2010JV4444   | 53492  |

【讨论】:

谢谢@zealous。我需要按 asscssn 分组。我有近 5k 人,每个人都有多个重复项。我认为您的查询将采用整个表中最高的 asscid 并将其复制到所有其他人。这会破坏关系。【参考方案3】:

我了解到您正在寻找 update 声明 - 到目前为止没有提供其他答案。

update 查询的语法往往是针对每个数据库的。既然已经澄清您使用的是 Oracle,我建议您使用相关子查询。

您可以自行加入associates 表:

update cases c
set asscid = (
    select max(a1.asscid) 
    from associates a
    inner join associates a1 on a1.asscssn = a.asscssn
    where a.asscid = c.asscid
)

或者你也可以使用窗口函数:

update cases c
set asscid = (
    select max_asscid
    from (
        select asscid, max(asscid) over(partition by asscssn) max_asscid
        from associates
    ) a
    where a.asscid = c.asscid
)

Demo on DB Fiddleupdate查询执行后,cases表包含:

案号 |阿西德 :----------- | -----: 2010JV0000 | 53492 2010JV1111 | 53492 2010JV2222 | 53492 2010JV3333 | 53492 2010JV4444 | 53492

【讨论】:

以上是关于Oracle 删除表中的重复行并使用另一个表中的值更新行的主要内容,如果未能解决你的问题,请参考以下文章

如何根据oracle中另一个表中的值更新一个表中的字段[重复]

从Oracle中删除表中的重复行

根据另一个表中的值更新表中的值[重复]

插入行并增加字段中的值

在Oracle中从表中删除重复行

Oracle 12c - 使用另一个表中的值在表中插入值