更改 SUM 返回 NULL 为零
Posted
技术标签:
【中文标题】更改 SUM 返回 NULL 为零【英文标题】:Changing a SUM returned NULL to zero 【发布时间】:2011-02-17 15:57:24 【问题描述】:我有一个存储过程如下:
CREATE PROC [dbo].[Incidents]
(@SiteName varchar(200))
AS
SELECT
(
SELECT SUM(i.Logged)
FROM tbl_Sites s
INNER JOIN tbl_Incidents i
ON s.Location = i.Location
WHERE s.Sites = @SiteName AND i.[month] = DATEADD(mm, DATEDIFF(mm, 0, GetDate()) -1,0)
GROUP BY s.Sites
) AS LoggedIncidents
'tbl_Sites contains a list of reported on sites.
'tbl_Incidents contains a generated list of total incidents by site/date (monthly)
'If a site doesn't have any incidents that month it wont be listed.
我遇到的问题是该站点本月没有任何事件,因此当我运行此 proc 时,我为该站点返回了一个 NULL 值,但我需要返回一个零/0在 s-s-rS 的图表中使用。
我尝试过使用 coalesce 和 isnull 无济于事。
SELECT COALESCE(SUM(c.Logged,0))
SELECT SUM(ISNULL(c.Logged,0))
有没有办法正确格式化?
干杯,
李
【问题讨论】:
【参考方案1】:把它放在外面:
SELECT COALESCE(
(
SELECT SUM(i.Logged)
FROM tbl_Sites s
INNER JOIN tbl_Incidents i
ON s.Location = i.Location
WHERE s.Sites = @SiteName AND i.[month] = DATEADD(mm, DATEDIFF(mm, 0, GetDate()) -1,0)
GROUP BY s.Sites
), 0) AS LoggedIncidents
如果要返回多行,请将 INNER JOIN 更改为 LEFT JOIN
SELECT COALESCE(SUM(i.Logged),0)
FROM tbl_Sites s
LEFT JOIN tbl_Incidents i
ON s.Location = i.Location
WHERE s.Sites = @SiteName AND i.[month] = DATEADD(mm, DATEDIFF(mm, 0, GetDate()) -1,0)
GROUP BY s.Sites
顺便说一句,如果没有保证,请不要将任何函数或表达式放在聚合函数中,例如不要将 ISNULL、COALESCE 放在 SUM 中,在聚合中使用函数/表达式会削弱性能,查询将使用表扫描执行
【讨论】:
我在为我所面临的问题找到的许多答案中感到困惑,但最终“COALESCE(SUM(i.Logged),0)” 成功了,而且非常优雅和简单的方法。谢谢!!【参考方案2】:你必须像这样使用ISNULL
-
ISNULL(SUM(c.Logged), 0)
或者,正如迈克尔所说,您可以使用左外连接。
【讨论】:
【参考方案3】:您可以像这样将 SELECT 包装在另一个 SELECT 中:
CREATE PROC [dbo].[Incidents]
(@SiteName varchar(200))
AS
SELECT COALESCE(TotalIncidents ,0)
FROM (
SELECT
(
SELECT SUM(i.Logged) as TotalIncidents
FROM tbl_Sites s
INNER JOIN tbl_Incidents i
ON s.Location = i.Location
WHERE s.Sites = @SiteName AND i.[month] = DATEADD(mm, DATEDIFF(mm, 0, GetDate()) -1,0)
GROUP BY s.Sites
) AS LoggedIncidents
)
【讨论】:
【参考方案4】:我发现完成此任务的最简单、最易读的方法是:
CREATE PROC [dbo].[Incidents]
(@SiteName varchar(200))
AS
SELECT SUM(COALESCE(i.Logged, 0)) AS LoggedIncidents
FROM tbl_Sites s
INNER JOIN tbl_Incidents i
ON s.Location = i.Location
WHERE s.Sites = @SiteName
AND i.[month] = DATEADD(mm, DATEDIFF(mm, 0, GetDate()) -1,0)
GROUP BY s.Sites
【讨论】:
如果在 tbl_Sites 中未找到任何行,则不计算 SUM 并返回 NULL。【参考方案5】:刚遇到这个问题,Kirtan 的解决方案对我来说效果很好,但是语法有点不对劲。我确实喜欢这样:
ISNULL(SUM(c.Logged), 0)
帖子帮助我解决了我的问题,非常感谢大家。
【讨论】:
但在 oracle 中找不到 ISNULL @Gank 在 Oracle 中你可以使用 NVL 函数来达到这个目的。【参考方案6】:我在 Oracle 中遇到了这个问题。
Oracle 没有ISNULL()
函数。但是,我们可以使用NVL()
函数来实现相同的结果:
NVL(SUM(c.Logged), 0)
【讨论】:
以上是关于更改 SUM 返回 NULL 为零的主要内容,如果未能解决你的问题,请参考以下文章