2016-07-26 51 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。當這與兩個六位數相加時,結果與添加各列的總和不同。

相關問題