Sql 在选择列表中选择子查询

Sql 在选择列表中选择子查询,sql,oracle,oracle-apex,oracle-apex-5.1,Sql,Oracle,Oracle Apex,Oracle Apex 5.1,Difference是time\u test中的一列,该列为空,并且:p13\u id是Oracle Apex的页面项 我知道我需要将其包装在nvl或类似的函数中,但我不知道如何包装。看起来您实际上是在尝试进行更新,而不是插入: insert into time_test(Difference) values (select ((select actual from time_test where id = :p13_id) - (select (monday+tuesday+wedne

Difference
time\u test
中的一列,该列为空,并且:p13\u id是Oracle Apex的页面项


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

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

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)
如果任何“day”列可能为空,则可以使用或将其默认为零,这样它们就不会中断计算:

update time_test
set difference = actual - (monday+tuesday+wednesday+thursday+friday)
where id = :p13_id
您还可以执行
合并(实际值,0)
,但如果未设置,则将差异保留为null可能更有意义。这取决于你想在那种情况下看到什么


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



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

为什么要使用子查询?该值实际上是空的,还是没有匹配的行?您是否真的在查询的同一个表中插入新行(insert语句中只有一列),或者您是否真的在尝试根据同一行中的其他值更新该列?现在您提出了问题,我想我正在尝试更新该行。更新时间\u测试集差异=实际-(选择(星期一+星期二+星期三+星期四+星期五)其中id=:p13_id你能解释一下nv1()吗?我不完全理解。在执行操作时,我已将默认值设置为0,但如果我有500个页面项,则很难将所有500个设置为0,如果我没有将其设置为0。结果是错误的。我不确定你的意思。
nvl(星期一,0)
将为受更新影响的每一行独立计算
monday
的值;对于每一行,如果该行的列值为null,则它将仅用零替换该行。无论如何,您似乎一次更新一行。(不知道“执行操作我已设置默认值”是什么意思)很抱歉)。我不知道nvl函数是什么。我开始用谷歌搜索它,我理解了它。它帮了我很多忙。由于愚蠢的空值,我无法执行任何操作。我一直认为空值是0,而不是没有值,所以我有点忘了它。
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