【问题标题】:Union replacing row if id is the same如果 id 相同,则联合替换行
【发布时间】:2021-12-18 22:16:13
【问题描述】:

我有 2 个具有相同数据结构的不同表,表 A 和 B,是否可以从 A 和 B 获取值,如果 B 中存在 ID 条目,它会替换 A 中的值?

例子:

select '1' as id, 'Bob' as "user" from dual
union
select '1' as id, 'Alice' as "user" from dual

这会返回:

1   Bob
1   Alice

如果id 在第二次选择中相同,我希望只有一行:

1   Alice

【问题讨论】:

  • 对我来说,这听起来像是外连接而不是联合。
  • 使用更新进行 JOIN。
  • 如果您的表是user,则执行union 操作以获取符合您条件的所有ID 是没有意义的。对你来说,第一和第二意味着什么?
  • @James "user" 不是表,而是列名。这两个表在示例中由内联 select 语句表示,从“dual”中选择,因为 Oracle 不允许使用没有表的 select 语句。

标签: sql oracle oracle12c


【解决方案1】:

您需要一个“FULL OUTER JOIN”而不是 UNION,它会为您提供三种类型的行:

  • 两个表都有匹配 id 的行,两个表的值都来自两个表(INNER JOIN 将返回的行)
  • 只有表 A 具有该 ID 的行,表 B 的列为空(LEFT OUTER JOIN 将返回的附加行)
  • 只有表 B 具有该 ID 的行,表 A 的列为空(RIGHT OUTER JOIN 将返回的附加行)

然后您可以使用 COALESCE 从 B 中获取值(如果存在)(第一种和第二种类型的行),如果不存在则从 A 中获取值(第三种类型的行)。

所以对于你的例子:

Select
    Coalesce(B.id, A.id) as id,
    Coalesce(B."user", A."user") as "user"
From
    (select '1' as id, 'Bob' as "user" from dual) as A
Full Outer Join
    (select '1' as id, 'Alice' as "user" from dual) as B
    On B.id = A.id

返回:

id user
1 Alice

(注意:在 SQL Server 上测试,通过删除“from dual”,因为我没有要测试的 Oracle DB。)

【讨论】:

    【解决方案2】:

    一种方法是:

    select '1' as id, 'Bob' as "user" from table_A
    where id not in (select id from table_B)
    union all
    select '1' as id, 'Alice' as "user" from table_B
    

    【讨论】:

      【解决方案3】:

      您可以使用 ROW_NUMBER() over (PARTITION BY id order by tab) 尝试这种方式 其中“tab”是表名,在本例中来自 table_a 的数据将获得优先权并被拾取。

      create table table_a as 
      (
      select '1' as id, 'Bob' as "user" from dual
      UNION
      select '2' as id, 'Jack' as "user" from dual
      ) ;
      
      create table table_b as 
      (
      select '1' as id, 'Alice' as "user" from dual -- table 
      UNION
      select '3' as id, 'John' as "user" from dual -- table
      ) ;
      
      select * from (
      select ROW_NUMBER() over (PARTITION BY id order by tab) rnum,id, "user"
       from( 
      select id, "user", 'A' tab from table_a 
      union all
      select id, "user", 'b' tab from table_b  
      ) 
      ) WHERE RNUM = 1;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-03-05
        • 2011-06-28
        • 2016-04-03
        • 1970-01-01
        • 2020-01-25
        • 2017-12-30
        • 1970-01-01
        相关资源
        最近更新 更多