2011-06-29 45 views
7

我想空結果集的聚集體爲0。我曾嘗試以下:骨料空結果集

SELECT SUM(COALESCE(capacity, 0)) 
    FROM objects 
WHERE null IS NOT NULL; 

結果:

sum 
----- 

(1 row) 

Subquestion:不會在Oracle上面的工作中,使用SUM(NVL(capacity, 0))

+0

你會得到什麼錯誤? –

回答

8

the documentation page有關集合函數:

應當指出的是,除了count,當沒有選擇行這些功能返回空值。特別是,沒有行的sum返回null,而不是像預期的那樣爲零。必要時可以使用​​3210函數將零替換爲空。

所以,如果你想保證一個返回值,適用COALESCE結果SUM,而不是它的參數:

SELECT COALESCE(SUM(capacity), 0) … 

對於甲骨文subquestion',好吧,我找不到在官方文檔頁面的NULL任何概念(the one for 10.2,特別是),但其他兩個來源是明確的:

也就是說,您不需要將NVL應用於capacity。 (但是,就像在PostgreSQL的COALESCE,您可能希望將它應用到SUM

+0

不應該用'用零代替零'而不用引用'用零代替null'嗎?但我不是母語的。 –

+0

@VlastimilOvčáčík:我也不是。希望那些在文檔中寫下那段話的人是! :)儘管如此,這句話是正確的英語。 「用B替代A」的含義與「替換*或*用A替換B」的含義相同。英語語法 - 去圖! –

+0

你是[right](http://english.stackexchange.com/questions/23360/substitute-x-for-y)!但它是棘手的。 –

5

事情是,聚合總是返回一個行,即使沒有行聚合(如在您的查詢情況)。你總結了一個沒有行的表達式。因此你得到的是空值。

試試這個:

select coalesce(sum(capacity),0) 
from objects 
where false; 
+1

因爲sum()會忽略空值,所以你可以用coalesce(sum(capacity),0)來簡化它。 – peufeu

+0

@peufeu:true,但是如果他的實際查詢使用左連接,則null +任何東西都會返回null,就像加上可能爲空的字段一樣。 –

+1

peufeu是對的。 SUM內部的合併是多餘的。看到我的答案代碼模擬 –

1

只是這樣做:

SELECT COALESCE(SUM(capacity), 0) 
FROM objects 
WHERE null IS NOT NULL; 

順便說一句,COALESCE SUM裏面是多餘的,即使容量爲NULL ,它不會使摘要爲空。

機智:

create table objects 
(
    capacity int null 
); 

insert into objects(capacity) values (1),(2),(NULL),(3); 

select sum(capacity) from objects; 

,將返回值6,不爲空。

而聚合函數內coalesce是性能殺手也一樣,你的RDBMS引擎不能僅僅通過所有行裂口,它有它的值是零,以評估每一行的列。我已經看到了一些OCD查詢,其中所有的聚合查詢都有一個聚合內部,我認爲最初的開發者有一個症狀Cargo Cult Programming,查詢的方式非常sloooowww。我刪除了SUM內部的合併,然後查詢變得很快。

0

雖然這個職位是很老了,但我想更新我在這樣的情況下

SELECT NVL(SUM(NVL(capacity, 0)),0) 
FROM objects 
WHERE false; 

使用這裏的外部NVL避免情況下,當有結果集中沒有行。內部NVL用於空列值,考慮(1 + null)的情況,它將導致null。所以內部NVL在其他列中默認值0中也是必要的。