2016-07-26 49 views
1

我想计算Oracle查询中的多个列。显然,你如何编写它有很大的不同。这是两种可能性我已经试过:在Oracle中统计多个列有什么不同?

select sum(column1 + column2 + column3) from ... 
select sum(column1) + sum(column2) + sum(column3) from ... 

表是一样的,连接是相同的,在WHERE子句是一样的,等等。然而,当我运行查询,第一个结果在15,481.19,第二个查询在14,385.69。这是相当不同的...

如果将所有数据导出到Excel并尝试获取所有值的总和,则结果与第二个查询相同。在Excel中,我尝试添加他们,以多种方式:

  • 只需选择所有数据
  • 计算各列的总和,并把它们加起来
  • 计算各行的总和,并把它们加起来

当我尝试在代码中获取所有数据,并将其代码添加到代码中而不是在查询中时,我也会得到与第二个查询相同的结果,并且与Excel中的结果相同。

问题是Oracle文档中另有说明:http://docs.oracle.com/javadb/10.8.2.2/ref/rrefsqlj13083.html。正如你在这个链接中看到的,他们说要使用第一个查询。

FYI:

  • 用于该用12.1.0版本的Oracle客户端。
  • 我在Oracle SQL Developer和Toad中都试过它。

基于这些测试,我现在知道我需要使用第二个查询来获得正确的结果,但我想了解为什么第一个查询结果比预期结果不同。有人对这个有经验么?这些查询如何返回不同的结果?

在此先感谢!

回答

3

简而言之:差异(最可能)源于聚合函数忽略空值的事实。

所以查询

select sum(column1 + column2 + column3) from ... 

相当于

select sum(column1 + column2 + column3) 
from ... 
where (column1 + column2 + column3) is not null; 

由于例如所述结果1 + nullnull

但查询

select sum(column1) + sum(column2) + sum(column3) from ... 

相当于

select sum(column1) + sum(column2) + sum(column3) 
from ... 
where column1 is not null 
    or column2 is not null 
    or column3 is not null; 

假设下面的数据:

column1 | column2 | column3 
--------+---------+-------- 
     1 | (null) | (null) 
(null) |  1 | (null) 
(null) | (null) |  1 
     1 |  1 |  1 

然后查询:

select * 
from ... 
where (column1 + column2 + column3) is not null; 

仅返回与(1,1,1)并且因此该行的结果将是3

但查询

select * 
from foo 
where column1 is not null 
    or column2 is not null 
    or column3 is not null; 

返回的所有行,因此总和为6(1为值从总和第一行第二行和第三行总计第三行)

+0

感谢您的澄清! – user2286826

2

您会看到加法运算符和求和函数如何处理空值的影响。如果总和包含空值,则它们基本上被忽略;但是如果将空值添加到另一个数字,则结果为空。从the documentation

如果运算符被赋予一个空操作数,那么结果总是为空。唯一不遵循此规则的运算符是串联(||)。

and

所有聚合函数,除了COUNT(*),分组和GROUPING_ID忽略空值。您可以在聚合函数的参数中使用NVL函数将值替换为空值。 COUNT和REGR_COUNT永远不会返回null,但会返回一个数字或零。对于所有剩余的集合函数,如果数据集不包含行,或者只包含具有空值的行作为聚合函数的参数,则函数返回null。

你可以看到一个带有虚拟表的效果:

create table t42 (column1, column2, column3) as 
select 1, 2, 3 from dual 
union all select 1, null, -3 from dual 
union all select 1, null, 3 from dual; 

您的疑问得到类似的效果:

select sum(column1 + column2 + column3) from t42; 

      SUM(COLUMN1+COLUMN2+COLUMN3) 
--------------------------------------- 
            12 

select sum(column1) + sum(column2) + sum(column3) from t42; 

SUM(COLUMN1)+SUM(COLUMN2)+SUM(COLUMN3) 
--------------------------------------- 
            10 

如果你做的列此外,你可以看到为什么:

select column1, column2, column3, column1 + column2 + column3 from t42; 

    COLUMN1 COLUMN2 COLUMN3     COLUMN1+COLUMN2+COLUMN3 
---------- ---------- ---------- --------------------------------------- 
     1   2   3          6 
     1     -3           
     1   2   3          6 

第二个加法结果为空,而不是-2。当这与两个六位数相加时,结果与添加各列的总和不同。

相关问题