Select select 中的子查询

Select sub queries within a select

insert into time_test(Difference) values 
(select ((select actual from time_test where id = :p13_id)  - 
(select 
(monday+tuesday+wednesday+thursday+friday) from time_test where id= 
:p13_id 
)) from time_test where id= :p13_id)

Differencetime_test 中的一个列,它是空的,而 :p13_id 是 Oracle Apex 的一个页面项目。

我知道我需要将它包装在 nvl 或类似的函数中,但我不知道如何。

看起来您实际上是在尝试进行更新,而不是插入:

update time_test
set difference = actual - (monday+tuesday+wednesday+thursday+friday)
where id = :p13_id

如果任何 'day' 列可能为空,那么您可以使用 nvl() or coalesce() 将它们默认为零,这样它们就不会破坏计算:

update time_test
set difference = actual - coalesce(monday, 0) - coalesce(tuesday, 0)
  - coalesce(wednesday, 0) - coalesce(thursday, 0) - coalesce(friday, 0)
where id = :p13_id

您也可以 coalesce(actual, 0) 但如果未设置差异,则将差异保留为 null 可能更有意义。这取决于你想在那种情况下看到什么。


在这种情况下,nvl()coalesce() 函数是等效的。如果第一个参数 - 例如monday - 为空则第二个参数被替换。所以 nvl(monday, 0) 如果它不为空,会给你 monday 的实际值,但如果它为空,会给你零。您将从 coalesce() 获得相同的效果,但它允许对多个表达式的列表进行求值,并将 return 列表中的第一个非空值。


另一种方法是使 difference 成为动态计算的虚拟列,或者在 table 的视图中计算它;两者都可以消除重复的数据存储和自己维护价值的需要。如果您确实想要一个物理列,您可以从触发器中设置它,以便在任何其他列在您的 Apex 应用程序之外更新时自动进行维护。但虚拟专栏可能更简单、更整洁。