【问题标题】:SQL discrepancy between addition of columns and summing of a columns with NULL values添加列和对具有 NULL 值的列求和之间的 SQL 差异
【发布时间】:2017-04-03 16:43:16
【问题描述】:

当我将两列 vw 加在一起时,如果一个或两个总和是 NULL,则行的结果会给出 NULL。这是有道理的。但是,如果我用SUM(v) 对列求和,即使有NULLs,也会有一个数字结果。这是因为实用吗?还是有理论上的依据?

这是一个澄清的例子(MySQL和sqlite):

CREATE TABLE x0 (
  id    INTEGER 
, v     DOUBLE
, w     DOUBLE
);

INSERT INTO x0 VALUES
  (1,    1,     1)
, (2,    1,     1)
, (3, NULL,     1)
, (4,    1,  NULL)
, (5, NULL,  NULL)
;

-- NULL if summand is NULL
SELECT v+w
FROM x0
;
-- v+w
-- 2
-- 2
-- \N
-- \N
-- \N

-- NULL if summand is NULL
SELECT id, v+w, SUM(v+w)
FROM x0
GROUP BY id
;
-- id   v+w SUM(v+w)
-- 1    2   2
-- 2    2   2
-- 3    \N  \N
-- 4    \N  \N
-- 5    \N  \N


-- There is numeric results even if some summands are NULL    
SELECT SUM(v), SUM(w)
FROM x0
;
-- SUM(v)   SUM(w)
-- 3        3

【问题讨论】:

  • SQL 远没有一个健全一致的理论基础。只需接受标准定义操作的方式即可。如果任何参数为NULL,“理论上”该值应为NULL,因为NULL 值是不确定的。
  • @GordonLinoff 我认为 SQL 是基于集合论的。因此,为了方便起见,在某些情况下,它似乎保留了数学的彻底性,例如,使用像 SUM 这样的函数。
  • 标准 SQL 只是忽略/删除聚合函数中的 NULL。否则,您将不得不在像 MIN(COALESCE(mycolumn, 9999999) 这样的 NULLable 列上使用 COALESCE,然后很难知道返回的 9999999 实际上是最小值还是 NULL 替换。
  • @giordano 。 . . 关系代数是基于集合论的。 SQL 松散地基于关系代数。您可以将其更多地视为受关系代数启发但由委员会创建的杂种,尽管这一切恰好做了很多有用的事情。

标签: mysql sql sqlite sum set-theory


【解决方案1】:

ISO/IEC 9075:1992 Database Language SQL 在第 6.5 节 (), General Rules, 1) b) 中说:

令 TX 为单列表,即 将 应用于 T 的每一行的结果 并消除空值

这就是它所说的。所以聚合函数必须忽略 NULL,但是,正式地,没有理由。

这种行为可以追溯到第一个 SQL 实现(IBM System R、Oracle V2),设计者可能认为这是一个好主意。后来,没有人想破坏向后兼容性。

在这方面,与其他方面一样,SQL's handling of NULL values 是不一致的,而且有时是不可移植的。

【讨论】:

    【解决方案2】:

    这是正常的。您必须使用适当的函数管理空值

    例如在mysql中

     SELECT id, ifnull(v,0)+infnull(w,0), SUM(ifnull(v,0)+infnull(w,0))
     FROM x0
     GROUP BY id
    

    http://rustyrazorblade.com/2006/09/mysql-number-null-null/ https://www.tutorialspoint.com/mysql/mysql-null-values.htm https://dev.mysql.com/doc/refman/5.7/en/working-with-null.html https://dev.mysql.com/doc/refman/5.7/en/control-flow-functions.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多