2013-05-04 44 views
0

我有一個使用了TOTAL()聚合函數的SQL查詢:與TOTAL()的SQLite查詢返回空行,拋出ConstraintException上閱讀

SELECT 
    c.Id, 
    c.Name, 
    ... 
    b.BatchNumber, 
    TOTAL(d.OrderedAmount) as TotalOrderedAmount 
FROM OrderProducts a 
LEFT JOIN WarehouseProducts b ON a.WarehouseProductId = b.Id 
... 
WHERE a.OrderId = @OrderId 
AND (e.Status = @OrderedStatus OR e.Status IS NULL) 

(多餘的行爲清楚起見移除)

這即使沒有找到結果,查詢也會返回至少一行,導致每列都是DBNull(我假設)。當我嘗試將此查詢的結果加載到DataTable中時,由於空值,我得到一個ConstraintException。

如果我用0 as TotalOrderedAmount替換TOTAL()行,返回的行數爲0,一切正常。

我試過使用WHERE a.Id IS NOT NULL,但無論我嘗試,總是至少有一行返回。

如何修改此查詢,以便在沒有找到產品時返回的行數爲0,即使使用聚合函數?

+0

可能的解決辦法是在回答[這個問題](擴展方法http://stackoverflow.com/questions/ 7580929/mysqldatareader-datatable-fillreader-throws-constraintexception),這將允許您加載沒有約束的DataTable。 – davmos 2013-05-04 22:49:32

回答

1

這就是SQL中的聚合查詢的工作原理。 的SQLite documentation說一下:

如果SELECT語句沒有GROUP彙總查詢BY子句,然後在結果集中的每個集合表達式一旦整個數據集進行評估。結果集中的每個非集合表達式都會針對數據集的任意選定行進行一次評估。每個非聚合表達式都使用相同的任意選擇的行。或者,如果數據集包含零行,則將針對完全由NULL值組成的行評估每個非聚合表達式。

通過評估結果集中的聚合和非聚合表達式創建的單行結果集數據形成不帶GROUP BY子句的聚合查詢的結果。沒有GROUP BY子句的聚合查詢總是隻返回一行數據,即使輸入數據爲零行。

要允許空結果,必須從最外層的查詢中刪除聚合函數TOTAL。 爲了仍然得到這個值(如果有一個結果記錄),使用子查詢:

SELECT 
    c.Id, 
    c.Name, 
    ... 
    b.BatchNumber, 
    (SELECT TOTAL(d.OrderedAmount) 
    FROM SomeTable d 
    WHERE d.x = c.y -- or however d is related to the other tables 
    ) AS TotalOrderedAmount 
FROM OrderProducts a 
JOIN ...    -- without d here 
WHERE ...