带有分析的 Oracle 更新语句失败

Posted

技术标签:

【中文标题】带有分析的 Oracle 更新语句失败【英文标题】:Oracle update statement with analytics is failing 【发布时间】:2016-04-14 06:00:37 【问题描述】:

Table_B 包含重复记录,如下所示。我要做的是使用 Table_B.SERIAL_NUM 查找 Table_A 并使用 Table_B 中 COVERAGE_TO 列中的最新日期值更新 Table_A .COVERAGE_END 列。

表_B

SERIAL_NUM  ,COVERAGE_FROM  ,COVERAGE_TO 
123456  ,26/12/2014 ,13/12/2015
123456  ,14/12/2015 ,13/12/2016
23456   ,18/12/2014 ,13/12/2015
23456   ,14/12/2015 ,13/12/2016

以下是我正在使用的更新语句。

update Table_A J
set ( J.COVERAGE_END_DATE)
=(select COVERAGE_TO from 
(
select SERIAL_NUM, COVERAGE_TO, row_number() over(partition by SERIAL_NUM order by COVERAGE_TO desc) as rn from  TABLE_B B

)where rn = 1
)
where exists
(
select * from TABLE_B Q where Q.SERIAL_NUM = J.SERIAL_NUMBER
)
;

但是我得到以下错误

ORA-01427: single-row subquery returns more than one row

有人可以帮我解决这个问题吗?

【问题讨论】:

为什么要在 B 上进行分区(这需要 top(1))?为什么不直接从 B 获取 max(coverage_to)? 如您所见,序列号在表 B 中重复。因此,对于特定的 SN,我需要表 B 中的最新日期。然后我需要使用该日期更新表 A。表 因为序列号是唯一值。我不是 Oracle 方面的专家,如果你能告诉我如何以你的方式实现同​​样的目标,我会试一试。 【参考方案1】:

您必须将 J 的 SERIAL_NUMBER 与 B 进行比较才能获得唯一正确的值。

 where rn = 1 and J.SERIAL_NUMBER = SERIAL_NUM

如果不是,子查询将返回每个 SERIAL_NUM 的最大值。

【讨论】:

【参考方案2】:

我不确定这里为什么需要分区。 一个简单的 MAX() 不会产生所需的结果吗?

update table_a
   set coverage_end_date = (
     select max(coverage_to)
       from table_b b inner join table_a a on b.serial_num = a.serial_num
   )
;

【讨论】:

以上是关于带有分析的 Oracle 更新语句失败的主要内容,如果未能解决你的问题,请参考以下文章

带有错误 ORA-00904 的 Oracle 更新语句

带有在子查询中生成的值的 Oracle SQL 更新语句

具有组功能的 Oracle 更新语句

使用 not in 语句 Oracle 更新查询

带有子查询的 Oracle 更新 - 性能问题

Oracle 语句如何转义