1

我有一个使用TOTAL()聚合函数的 SQL 查询:

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 中时,由于 null 值,我得到一个 ConstraintException。

如果我用 替换该TOTAL()0 as TotalOrderedAmount,则返回的行数为 0,一切正常。

我尝试过使用WHERE a.Id IS NOT NULL,但无论我尝试什么,似乎总是至少返回一行。

如何修改此查询,以便在未找到产品时返回的行数为 0,即使使用聚合函数?

4

1 回答 1

1

这就是 SQL 中聚合查询的工作方式。SQLite 文档对此进行了说明:

如果 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 ...
于 2013-05-05T10:04:52.740 回答