2015-06-04 52 views
-1

當我執行下面的代碼:COALESCE沒有在PostgreSQL的工作

CREATE TABLE Unsubscriptions (
    Email varchar(80) NOT NULL PRIMARY KEY, 
    Unsubscribed boolean NOT NULL 
); 
SELECT COALESCE(Unsubscribed, FALSE) FROM Unsubscriptions WHERE Email = 'nnn'; 

我想到的是,選擇不會返回NULL值,這是因爲,根據PostgreSQL的文檔COALESCE操作返回第一個非NULL值來自參數(在這種情況下爲FALSE)。

但是,在我的Amazon RDS實例上,即使表中沒有條目,上面的代碼仍會返回NULL,但應該使用第二個參數。

爲什麼COALESCE函數不返回FALSE值?

+0

似乎是Amazon RDS特有的。 – JiriS

+2

你的問題有些問題,你的專欄'退訂'已經不是空的。這意味着您的選擇無法返回null –

+0

@Aツ如果表中沒有與條件匹配的條目,則它可以返回NULL。我也在其他數據庫中測試過它,它工作。 – user1613797

回答

3

我覺得這是關鍵,你的誤解:

仍返回NULL,即使在表中沒有條目

如果在表中沒有行,將有在簡單的SELECT的輸出中沒有行。 COALESCE更改特定列中的值,但不能創建額外的行。

正如其他人所指出的,在表中任何行約束爲NOT NULL,所以COALESCE不會有任何影響。

你大概看到的是一個空集在你正在查詢數據的應用程序中,導致類似於其中的一個集合NULL的行爲。請注意,具有零行的SQL結果集仍將具有名稱和類型的列(將它們視爲空格的標題)。

如果你想保證你總是有至少一行,你也許可以UNION虛設行到的結果:

SELECT Unsubscribed FROM Unsubscriptions WHERE Email = 'nnn' 
UNION 
SELECT false as Unsubscribed 

這個虛擬的行會在那裏,以及任何實際的結果,如果有的話,如果你沒有在應用程序代碼中跳過它的麻煩,你需要一個更聰明的解決方案。

1

根據您的文章UnsubscribedNOT NULL列,如下所示,那麼使用COALESCE()函數根本沒有意義。至少我沒看見。

Unsubscribed boolean NOT NULL 

NULL和空行是兩個不同的東西放在一起。此外,如果您的表格爲空,則條件WHERE Id = 'nnn'將永遠不會滿足,因此不會返回任何行。即使你做了一個簡單的select結果將是空的結果集。如果一列被標記爲NOT NULL,那麼你永遠不會在那裏輸入NULL的值,因此在返回NULL時沒有意義。

+0

幾乎沒有任何關係如果列被標記爲NOT NULL,那麼並不意味着結果不能爲NULL。只需在空表上執行SELECT Unsubscribed FROM Unsubscriptions WHERE Id ='nnn',它將返回NULL,因爲沒有條目。 – user1613797

+1

它不會返回單行 –

+0

@ user1613797,NULL和空行是兩個不同的東西在一起。 – Rahul