2016-08-15 62 views
2

我有兩個表,servicesextraFees,相關的1xn到services.id = extraFees.serviceId。我的問題是,當我對s.ids.category的不存在的組合執行以下查詢時,我仍然得到1 row(s) returned,所有字段均爲NULL。MIN()導致MySQL返回所有NULL行而不是0行

SELECT 100 + (s.feeRate * MIN(ef.extra)) AS extraFees FROM services s 
LEFT JOIN extraFees ef ON s.id=ef.serviceId WHERE s.id=12 AND s.category='PRG' 

我知道罪魁禍首是MIN(),因爲如果我用一個數字或NULL替換它,我得到0 row(s) returned,這就是我想要的。

SELECT 100 + (s.feeRate * 5) AS extraFees FROM services s 
LEFT JOIN extraFees ef ON s.id=ef.serviceId WHERE s.id=12 AND s.category='PRG' 
SELECT 100 + (s.feeRate * NULL) AS extraFees FROM services s 
LEFT JOIN extraFees ef ON s.id=ef.serviceId WHERE s.id=12 AND s.category='PRG' 

爲什麼會發生這種情況,我該如何避免它?

回答

4

聚合函數將返回結果。試試這個:

CREATE TABLE x(id int); 
SELECT MIN(id) FROM x 

你會得到1行:NULL。

SELECT y.id 
    FROM (SELECT MIN(id) AS id FROM x) y 
    WHERE y.id IS NOT NULL 

或使用HAVING條款:如果你想 忽略NULL結果,您可以在子查詢包裹。

4

發生這種情況是因爲MIN() returns NULL if there were no matching rows

我該如何避免它?

嘗試將調用包裝到子查詢中的MIN()以過濾出NULL。

編輯:

我讀過的文檔,但我沒有看到MIN()返回的NULL是如何從 我在最後一個查詢手動指定NULL不同。

我懷疑這是因爲你的第二組查詢不是聚合查詢。 聚合查詢將返回行上的聚合結果。 如果沒有行,則查詢返回NULL。

另一方面,第二組查詢不是聚合查詢,那些查詢可以返回一個「空集」作爲邏輯結果。

+0

我讀過那個文檔,但是我看不到MIN()返回的NULL與我在最後一個查詢中手動指定的NULL不同。 – user3748908

+0

@ user3748908只需使用NULL,不會觸發聚合計算,因此在基表上完成所有過濾之後,不會顯示任何行。使用'MIN'強制總是返回一行的聚合操作。過濾完成後(不返回任何行),將對空結果集進行聚合計算,結果爲具有「NULL」值的一行。 – Glenn