如果未找到记录则返回零

33

我有一个存储过程内部的查询,用于计算表格中一些值的总和:

SELECT SUM(columnA) FROM my_table WHERE columnB = 1 INTO res;

执行此选择后,我会用另一个查询检索到的整数值从res值中减去并返回结果。如果验证了WHERE子句,则一切正常。但如果没有验证,则我的函数返回的只是一个空列(可能是因为我试图用空值减去整数)。

如果WHERE子句不满足条件,如何使我的查询返回零?


1
在“SELECT…”后添加“INTO var”仅适用于PL/pgSQL代码,而不适用于普通SQL。我猜这是PL/pgSQL函数或“DO”语句的一部分。正确吗? - Erwin Brandstetter
5个回答

62

你可以:

SELECT COALESCE(SUM(columnA), 0) FROM my_table WHERE columnB = 1
INTO res;

这是有效的,因为您的查询具有聚合函数,因此即使在底层表中未找到任何内容,也会始终返回一行。

如果没有聚合,普通查询将在这种情况下返回无行。在这种情况下,COALESCE 将永远不会被调用,也无法帮助您。当处理单个列时,我们可以将整个查询包装起来:

SELECT COALESCE( (SELECT columnA FROM my_table WHERE ID = 1), 0)
INTO res;

对于您最初的查询也适用:

SELECT COALESCE( (SELECT SUM(columnA) FROM my_table WHERE columnB = 1), 0)
INTO res;

COALESCE() 在手册中的更多内容
聚合函数在手册中的更多内容
此后帖子中提供了其他选择


2
@FreshPrinceOfSO:我认为应该指出 COALESCESQL标准 的方法来执行它。 - Erwin Brandstetter
1
我曾经与 COALESCE 有过一段不愉快的经历,我们现在可以说已经不再是朋友了。 - Kermit
4
“@FreshPrinceOfSO,更准确地说,我对SQL Server有过不好的经历,而不是对COALESCE函数有过不好的体验。在其他关系型数据库管理系统中,使用COALESCE是没有问题的。” - Ihor Romanchenko

4

虽然不熟悉PostgreSQL,但在SQL Server或Oracle中,使用子查询可以像下面这样工作(在Oracle中,SELECT 0将是SELECT 0 FROM DUAL

SELECT SUM(sub.value)
FROM
( 
  SELECT SUM(columnA) as value FROM my_table
  WHERE columnB = 1
  UNION
  SELECT 0 as value
) sub

也许这对于Postgresql也适用?

1
你也可以尝试:(我尝试过这个方法,并且对我有效)
SELECT ISNULL((SELECT SUM(columnA) FROM my_table WHERE columnB = 1),0)) INTO res;

0

您可以使用exists子句。

IF EXISTS(SELECT  FROM my_table WHERE columnB = 1)
      THEN
         res := SUM(columnA);
      ELSE
         res := 0
      END IF;

0

COALESCE应该能解决问题,例如:

(SELECT columnA from my_table where columnB=123) - 
COALESCE((SELECT SUM(columnA) FROM my_table WHERE columnB = 1 INTO res),0)

这里,如果第二个选择查询没有返回任何行,则默认为0。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接