Oracle 按顺序连接行,其中每个表上的顺序定义不同

Posted

技术标签:

【中文标题】Oracle 按顺序连接行,其中每个表上的顺序定义不同【英文标题】:Oracle join rows in order where order is defined differently on each table 【发布时间】:2015-02-17 13:56:02 【问题描述】:

我有两张桌子

包含 project_id、id 和 load_date 列的 TABLE_A

和带有列 project_id、delete_flag 和 delete_date 的 TABLE_B

其中 TABLE_A.load_date 是一个新列,我想根据历史数据的 TABLE_B.delete_date 填充它。基本上,一个文件被反复加载到系统中,而历史上我们没有跟踪它何时加载。但是,每次重新加载文件时,它的先前版本都会在 TABLE_B 中使用 delete_date 更新(即软删除)。以前的版本只是保留在 TABLE_A 中,没有任何更改。

我想根据 TABLE_B 中的匹配项目填充 TABLE_A.load_date。 TABLE_A 中最旧的行(最小的 TABLE_A.id)与 TABLE_B 中最旧的行(最旧的 delete_date)相匹配。因此,如果您继续从每个表中按顺序选择下一个,则这些行应该匹配。但我不知道如何将其转换为 Oracle 语句。到目前为止,我所得到的是这不涉及行顺序匹配:

MERGE INTO TABLE_A a 
USING 
(
  SELECT PROJECT_ID, DELETE_DATE
  FROM TABLE_B
  WHERE DELETE_FLAG = 'Y'
  ORDER BY DELETE_DATE ASC
) b ON (a.PROJECT_ID = b.PROJECT_ID)
WHEN MATCHED THEN UPDATE 
    SET a.LOAD_DATE = p.DELETE_DATE;

【问题讨论】:

这不需要高效,因为它只是一次性工作。 请显示示例数据和预期输出。排序依据对您的合并语句没有影响。 您是否尝试过在 FROM 子句中编写一个带有两个独立子查询的查询,每个子查询以正确的顺序返回数据以及一个 ROWNUM 虚拟列,并加入第 num 行?我会自己尝试,但我现在无法访问 Oracle。 @PlanItMichael 谢谢,看起来 Ponder Stibbons 已经做到了!它确实有效 - 我不知道如何使订单在连接中生效。 【参考方案1】:

就我正确理解您的标准而言,此合并应该可以完成工作:

merge into table_a ta
using (
  select pid project_id, id, delete_date
    from (
      select project_id pid, id, 
          row_number() over (partition by project_id order by id) rn
        from table_a) a
    join (
      select project_id pid, delete_date, 
          row_number() over (partition by project_id order by delete_date ) rn
        from table_b
        where delete_flag='Y') b using (pid, rn) ) tb 
on (ta.project_id = tb.project_id and ta.id = tb.id)
when matched then update
  set ta.load_date = tb.delete_date

【讨论】:

以上是关于Oracle 按顺序连接行,其中每个表上的顺序定义不同的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有主键的表上按顺序更新表?

Postgres中用户定义的连接功能?

相同列上的 Oracle 2 索引但顺序不同

Oracle SQL 顺序连接数据

两个链表第一个公共结点

使用触发器删除 Oracle 表中的行