简体   繁体   English

为什么我的非零分母在 SQL 中给出“除以零”错误?

[英]Why is my non-zero denominator giving a “division by zero” error in SQL?

First time asking a question here, thanks in advance.第一次在这里提问,先谢谢了。 Also new to SQL so this may be a basic question. SQL 也是新手,所以这可能是一个基本问题。

I'm in charge of a weekly errors report for our product and trying to come up with a "smarter" query that'll only return cases where the number of errors represents a significant chunk of a customer's traffic (eg, don't show me 100,000 errors out of a customer's 50,000,000 sebsite visitors, but do show me 50,000 out of 200,000).我负责我们产品的每周错误报告,并尝试提出一个“更智能”的查询,该查询只会返回错误数量代表客户流量的重要部分的情况(例如,不显示我在客户的 50,000,000 名网站访问者中出现了 100,000 个错误,但确实显示了 200,000 个中的 50,000 个错误)。

Where this gets difficult is, I want to differentiate mobile from desktop traffic, and return a customer's data when either one gets a high percentage of errors (for now let's say 20%).困难的地方在于,我想将移动流量与桌面流量区分开来,并在其中任何一个出错率很高(现在假设为 20%)时返回客户的数据。

Here's what I have so far:这是我到目前为止所拥有的:

WITH requests_summary AS (
    SELECT customer_id, column_x, column_y, column_z
        SUM(CASE WHEN event = 'error' AND device = 'mobile' THEN 1 ELSE 0 END) AS err_mbl,
        SUM(CASE WHEN event = 'traffic' AND device = 'mobile' THEN 1 ELSE 0 END) AS trf_mbl
        SUM(CASE WHEN event = 'error' AND device = 'desktop' THEN 1 ELSE 0 END) AS err_desk,
        SUM(CASE WHEN event = 'traffic' AND device = 'desktop' THEN 1 ELSE 0 END) AS trf_desk
    FROM "table"
        WHERE timestamp >= DATEADD(day,-1, GETDATE())
        GROUP BY 1,2,3,4
)

SELECT *
FROM requests_summary
WHERE 1.0 * err_mbl / trf_mbl > 0.2
OR 1.0 * err_desk / trf_desk > 0.2;

Now the problem is, I get a 'division by zero' error every time I run this query.现在的问题是,每次运行此查询时都会出现“除以零”错误。 So far I've:到目前为止,我已经:

  • Commented out the desktop and mobile division conditions one at a time to verify they're both giving the error一次注释掉桌面和移动分区条件,以验证它们都给出了错误
  • Tried a separate query for just the CASE clauses, one at a time, to verify the traffic on each platform is non-zero (it's not really possible for a whole day to go with no traffic, anyway)尝试对 CASE 子句进行单独查询,一次一个,以验证每个平台上的流量是否非零(无论如何,对于 go 来说一整天都没有流量是不可能的)
  • Replaced the trf_mbl and trf_desk denominators with (A) an arbitrary non-zero number and (B) a COUNT(*), both made the query work将 trf_mbl 和 trf_desk 分母替换为 (A) 任意非零数和 (B) COUNT(*),两者都使查询工作

So I'm thinking the issue is with my use of the WITH clause to create the temporary requests_summary table, but I'm still not sure how to resolve this.所以我认为问题在于我使用 WITH 子句创建临时 requests_summary 表,但我仍然不确定如何解决这个问题。 I've been tinkering with this for a good chunk of the past two days, but still no go.在过去的两天里,我一直在修补这个问题,但仍然没有 go。 Can anyone offer guidance?任何人都可以提供指导吗?

The issue is in your where clause where you are dividing values.问题在于您要划分值的 where 子句。 in your where clause If either or both trf_mbl or trf_desk are equal to 0 you can get that error, meaning where there is not traffic event in that group ( customerid, x,y,z)在您的 where 子句中如果trf_mbltrf_desk中的一个或两个等于 0,您会收到该错误,这意味着该组中没有交通事件(customerid,x,y,z)

so you have to change your logic in the case there is no traffic event in that group.因此,如果该组中没有交通事件,则必须更改逻辑。

Use 'having' clause in the subquery to check for 0 traffic在子查询中使用“有”子句检查 0 流量

WITH requests_summary AS (
    SELECT customer_id, column_x, column_y, column_z
        SUM(CASE WHEN event = 'error' AND device = 'mobile' THEN 1 ELSE 0 END) AS err_mbl,
        SUM(CASE WHEN event = 'traffic' AND device = 'mobile' THEN 1 ELSE 0 END) AS trf_mbl
        SUM(CASE WHEN event = 'error' AND device = 'desktop' THEN 1 ELSE 0 END) AS err_desk,
        SUM(CASE WHEN event = 'traffic' AND device = 'desktop' THEN 1 ELSE 0 END) AS trf_desk
    FROM "table"
        WHERE timestamp >= DATEADD(day,-1, GETDATE())
        GROUP BY 1,2,3,4
        having trf_mbl>0 and trf_desk>0
)

SELECT *
FROM requests_summary
WHERE 1.0 * err_mbl / trf_mbl > 0.2
OR 1.0 * err_desk / trf_desk > 0.2;

I would simply rephrase the WHERE to be:我只想改写WHERE to be:

WHERE 1.0 * err_mbl > 0.2 * trf_mbl OR
      1.0 * err_desk > 0.2 * trf_desk

Voila.瞧。 No division.没有分工。 No error.没有错误。

Note: I am guessing that the 1.0 * is also not necessary.注意:我猜1.0 *也不是必需的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM