【问题标题】:Oracle Remove Duplicates and Update Rows in a Table with a Value from Another TableOracle 删除表中的重复行并使用另一个表中的值更新行
【发布时间】: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

【问题讨论】:

    标签: sql oracle join sql-update window-functions


    【解决方案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

    【讨论】:

      猜你喜欢
      • 2020-11-13
      • 1970-01-01
      • 2012-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-09
      相关资源
      最近更新 更多