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

问题描述

第一次在这里提问,先谢谢了。同样是 sql 新手,所以这可能是一个基本问题。

我负责我们产品的每周错误报告,并试图提出一个“更智能”的查询,该查询只会返回错误数量代表客户流量的很大一部分的情况(例如,don不要向我展示客户 50,000,000 名 sebsite 访问者中的 100,000 个错误,而是向我展示 200,000 名中的 50,000 个)。

这变得困难的地方在于,我想将移动流量与桌面流量区分开来,并在其中任何一个出现高比例错误(现在假设为 20%)时返回客户的数据。

这是我目前所拥有的:

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;

现在的问题是,每次运行此查询时,我都会收到“被零除”错误。到目前为止,我已经:

  • 一次一个注释掉桌面和移动部门的条件,以验证它们都给出了错误
  • 尝试单独查询 CASE 子句,一次一个,以验证每个平台上的流量是否为零(无论如何,一整天都没有流量是不可能的)
  • 将 trf_mbl 和 trf_desk 分母替换为 (A) 任意非零数字和 (B) COUNT(*),两者都使查询正常工作

所以我认为问题在于我使用 WITH 子句创建临时 requests_summary 表,但我仍然不确定如何解决这个问题。在过去两天的大部分时间里,我一直在修补这个问题,但仍然没有成功。谁能提供指导?

解决方法

问题出在您划分值的 where 子句中。 在您的 where 子句中如果 trf_mbltrf_desk 中的一个或两个等于 0,您会得到该错误,这意味着该组中没有交通事件( customerid,x,y,z)>

因此,如果该组中没有交通事件,您必须更改逻辑。

,

在子查询中使用 'have' 子句检查 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;
,

我会简单地将 WHERE 改写为:

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

瞧。没有分工。没有错误。

注意:我猜 1.0 * 也不是必需的。