在选择中选择子查询

时间:2018-08-13 17:06:35

标签: sql oracle oracle-apex oracle-apex-5.1

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或类似的函数中,但我不知道如何。

1 个答案:

答案 0 :(得分:1)

您似乎实际上是在尝试进行更新,而不是插入内容:

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

如果“天”列中的任何一列可能为空,则可以使用nvl()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),但如果未设置差异,则将差异保留为空可能更有意义。在这种情况下,这取决于您要查看的内容。


在这种情况下,nvl()coalesce()函数是等效的。如果是第一个参数-例如monday-为null,然后替换第二个参数。因此,nvl(monday, 0)如果不为空,将为您提供monday的实际值,但如果为空,则将为您提供零。您将从coalesce()中获得相同的效果,但是可以计算多个表达式的列表,并将返回列表中的第一个非null值。


另一种解决方法是使difference成为虚拟列,该虚拟列是动态计算的,或者是在表的视图中计算的;要么将删除重复的数据存储,要么需要自己维护价值。而且,如果您确实希望使用物理列,则可以从触发器中进行设置,以便自动维护,以防其他列在Apex应用程序外部更新。但是虚拟列可能更简单,更整洁。