【问题标题】:Return zero if no record is found如果没有找到记录,则返回零
【发布时间】:2013-07-24 05:39:49
【问题描述】:

我在一个存储过程中有一个查询,它对表中的一些值求和:

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

在此选择之后,我用另一个查询检索到的整数减去 res 值并返回结果。如果验证了WHERE 子句,则一切正常。但如果不是,我的函数返回的都是一个空列(可能是因为我尝试用一​​个空值减去一个整数)。

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

【问题讨论】:

  • INTO var 附加到SELECT ... 仅在 PL/pgSQL 代码中有效,在普通 SQL 中无效。我假设这是 PL/pgSQL 函数或 DO 语句的一部分。对吗?

标签: sql postgresql null plpgsql coalesce


【解决方案1】:

你可以:

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

这很有效,因为您的查询有一个聚合函数,因此总是返回一行,即使在基础表中没有找到任何内容。

在这种情况下,没有聚合的普通查询将返回 no rowCOALESCE 永远不会被调用,也无法拯救你。在处理单个列时,我们可以将整个查询包装起来:

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() in the manual.
更多关于aggregate functions in the manual.
更多替代品在后面的帖子中:

【讨论】:

  • @FreshPrinceOfSO:我认为应该注意COALESCESQL 标准 方式。
  • 我有一个bad experienceCOALESCE...假设我们不再是朋友了。
  • @FreshPrinceOfSO 更多的是I had a bad experience with SQL Server,然后是I had a bad experience with COALESCECOALESCE在其他RDBMS中没有问题。
【解决方案2】:

我不熟悉 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?

【讨论】:

    【解决方案3】:

    你也可以试试:(我试过了,对我有用)

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

    【讨论】:

      【解决方案4】:

      您可以使用exists 子句。

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

      【讨论】: