【问题标题】:SQL Divide by Zero ErrorSQL 除以零错误
【发布时间】:2015-03-03 11:46:55
【问题描述】:

我有一个烦人的问题,它阻止我生成一些数据; SQL作业一共23步,21日失败。

-- Step 21 Create the table z1QReportOverview
-- Create z1QReportProjectOverview.sql
-- Project Overview - By Category (Part 4).sql
USE database
SELECT z1QReportProjectOverview1.[ERA Category] AS Category,
z1QReportProjectOverview1.[Total Projects Signed],
z1QReportProjectOverview1.[Total Spend Under Review],
z1QReportProjectOverview1.[Avg. Project Size],
z1QReportProjectOverview2.[Work in Progress],
z1QReportProjectOverview2.[Implemented],
z1QReportProjectOverview2.[No Savings],
z1QReportProjectOverview2.[Lost],
CONVERT(decimal(18,0),[Lost])/CONVERT(decimal(18,0),[Total Projects Signed]) AS [Loss Ratio],
z1QReportProjectOverview2.[Completed],
(
    CONVERT(decimal(18,0),([Completed]+[Implemented]))/
    CONVERT(decimal(18,0),([Completed]+[Implemented]+[Lost]))
) 
AS [Success Ratio],
z1QReportProjectOverview3.[Avg. Spend] AS [Average Spend],
z1QReportProjectOverview3.[Avg. Savings] AS [Average Savings],
z1QReportProjectOverview3.[Avg. Savings %] AS [Average Savings %]
INTO dbo.z1QReportProjectOverview
FROM dbo.z1QReportProjectOverview1
JOIN dbo.z1QReportProjectOverview2
ON (z1QReportProjectOverview1.[ERA Category] = z1QReportProjectOverview2.[ERA    Category])
JOIN dbo.z1QReportProjectOverview3
ON (z1QReportProjectOverview2.[ERA Category] = z1QReportProjectOverview3.[ERA     Category])
ORDER BY Category

我相信我知道导致除以零错误的原因。

“丢失”字段由三个字段组成,在某些情况下(非常罕见)所有 3 个字段均为 0,导致“丢失”字段为 0。

我相信这是错误的主要原因,但那里也有第二个部门,我对 SQL 很垃圾,因此我的问题是:

我应该把 CASE WHEN 子句放在哪里?

-很可能这点也写错了:( "CASE When [Lost] = 0 SET [Total Projects Signed] = 0"

非常感谢任何建议!

【问题讨论】:

  • 当除数为零时,您可以使用案例来输出零,或者只是使用过滤器完全退出该记录以避免零除数(因为除以零是有意义的,因此踩上的记录并不罕见这也是意义),取决于您的要求
  • 每当我输入“/”时,我都会尝试输入以下代码。我无法获得任何宏来做到这一点,所以我必须依靠我的大脑。这是我尝试输入的内容:/NULLIF (divisor, 0)。详细解释见stackoverflow.com/questions/861778/…

标签: sql sql-server divide


【解决方案1】:

使用NULLIF 处理除以零错误

........
Isnull(CONVERT(DECIMAL(18, 0), [Lost]) / NULLIF(CONVERT(DECIMAL(18, 0), [Total Projects Signed]), 0), 0) AS [Loss Ratio],
Isnull(CONVERT(DECIMAL(18, 0), ( [Completed] + [Implemented] )) /
                        NULLIF(CONVERT(DECIMAL(18, 0), ( [Completed] + [Implemented] + [Lost] )), 0), 0) AS [Success Ratio], 
........

【讨论】:

    【解决方案2】:

    您可以使用CASE作为检查分割值是否为0

    CASE WHEN CONVERT(decimal(18,0),[Lost]) <> 0 THEN 
            CONVERT(decimal(18,0),[Lost])/CONVERT(decimal(18,0),[Total Projects Signed]) 
         ELSE 0 END AS [Loss Ratio],
    z1QReportProjectOverview2.[Completed],
    CASE WHEN CONVERT(decimal(18,0),([Completed]+[Implemented]+[Lost])) <> 0 THEN 
          (CONVERT(decimal(18,0),([Completed]+[Implemented]))/CONVERT(decimal(18,0),([Completed]+[Implemented]+[Lost]))) 
        ELSE 0 END AS [Success Ratio],
    

    【讨论】:

    • 两个语句之间的“z1QReportProjectOverview2.[Completed]”部分会发生什么情况? :)
    • 您可以保持原样。我只是没有写在这里,因为它与案件无关。
    【解决方案3】:

    你可以像这样使用CASE WHEN

    CASE 
         -- check if either value is 0 (which will cause error)
         WHEN CONVERT(decimal(18,0),[Lost]) = 0
           OR CONVERT(decimal(18,0),[Total Projects Signed]) = 0
         -- if so, return 0
         THEN 0
         -- otherwise perform calculation
         ELSE CONVERT(decimal(18,0),[Lost])/CONVERT(decimal(18,0),[Total Projects Signed])
    END AS [Loss Ratio]
    

    【讨论】:

    • 感谢您的快速反馈。评论代码帮助我理解了你是如何编码的。在 END AS[Loss Ratio] 之后有 z1QReportProjectOverview2.[Completed], (#Code) AS [Success Ratio],这部分在 END AS 之后还会运行吗?
    • @Justin 没问题。这是向查询中的一列添加检查的示例。如果需要,您也可以在其他字段上使用它,方法是将要检查的字段替换为 WHEN 部分,并且仅在值合适时才执行 ELSE 部分。
    【解决方案4】:

    @坦纳:

    所以像这样布置代码应该可以正常工作吧?

    CONVERT(decimal(18,0),[Lost])/CONVERT(decimal(18,0),[Total Projects Signed]) AS [Loss Ratio],
    CASE 
     -- check if either value is 0 (which will cause error)
     WHEN CONVERT(decimal(18,0),[Lost]) = 0
       OR CONVERT(decimal(18,0),[Total Projects Signed]) = 0
     -- if so, return 0
     THEN 0
     -- otherwise perform calculation
    ELSE CONVERT(decimal(18,0),[Lost])/CONVERT(decimal(18,0),[Total Projects Signed])
    END AS [Loss Ratio]
    z1QReportProjectOverview2.[Completed],
    (
        CONVERT(decimal(18,0),([Completed]+[Implemented]))/
        CONVERT(decimal(18,0),([Completed]+[Implemented]+[Lost]))
    ) 
    AS [Success Ratio],
    

    【讨论】:

    • 我相信我应该只拿出顶线。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-25
    相关资源
    最近更新 更多