使用 CAST FLOAT64 时仍然收到被零除的错误

Posted

技术标签:

【中文标题】使用 CAST FLOAT64 时仍然收到被零除的错误【英文标题】:Still receiving division by zero error when using CAST FLOAT64 【发布时间】:2020-10-07 13:12:11 【问题描述】:

编辑:经过一些实验,我更改了标题。 我在 BigQuery 中使用标准 SQL,并在尝试使用 CAST() 进行除法时得到除以零的错误

预留表架构:

平字符串 NULLABLE pay_day DATE NULLABLE %E4Y/%m/%d USD_amt INTEGER NULLABLE EANR 字符串可以为空

我可以做以下查询:

SELECT Flat, 
EXTRACT(YEAR FROM pay_day) AS Yr, 
SUM(CASE WHEN EANR='Cancelled' THEN USD_amt END) AS Cancel_rev,
SUM(USD_amt)AS Yr_rev
GROUP BY Flat, Yr
ORDER BY 1

哪个输出好:

Row Flat    Yr  Yr_rev  cancel_rev
1   null    null    null    null
2   1   2018    1994    null
3   1   2019    29709   100
4   1   2020    13588   5212
5   1A  2020    4432    null
6   1A  2021    0   null
            

我想实现以下目标:

Flat    Yr  Yr_rev  Cancel_rev  % revenue
                
1   2018    1994                  0.00%
1   2019    29709   100           0.34%
1   2020    13588   5212          38.36%
1A  2020    3767    2             0.05%
2   2019    10857   2             0.02%
2   2020    13890   4223          30.40%
2   2021    1014                  0.00%
3   2019    7965    233           2.93%
3   2020    18333   4143          22.60%
3   2021    10736                 0.00%
4   2020    0                     0.00% 

但我无法使用以下方法除以 Cancel_rev / Yr_rev 以获得 Cancel_rev_%,我收到错误“除以零:0 / 0”

SUM(CASE WHEN EANR='Cancelled' THEN CAST(USD_amt AS FLOAT64) END)/SUM(CAST(USD_amt AS FLOAT64)) AS Cancel_Rev_Perc 

解决此问题的最佳方法是什么?

【问题讨论】:

【参考方案1】:

经过一些试验,这似乎是由于 USD_amt 是整数的组合 并使用 NULL 值进行除法。如果我使用 SAFE_DIVIDE() 功能,它现在可以工作

SAFE_DIVIDE((SUM(CASE WHEN EANR='Cancelled' THEN USD_amt END)),(SUM(USD_amt))) as Cancel_rev_Perc

【讨论】:

【参考方案2】:

这回答了问题的原始版本。

使用窗口函数!

SELECT Flat, EXTRACT(YEAR FROM pay_day) AS Year, 
       (SUM(CASE WHEN EANR = 'Cancelled' THEN USD_amt END) /
        SUM(SUM(USD_amt)) OVER (PARTITION BY Flat, EXTRACT(YEAR FROM pay_day))
       ) AS Cancel_ratio
FROM `finances.reservations`
GROUP BY Flat, Year
ORDER BY 1;

在 BigQuery 中,您可以使用子查询来定义别名:

SELECT Flat, Year, 
       (SUM(CASE WHEN EANR = 'Cancelled' THEN USD_amt END) /
        SUM(SUM(USD_amt)) OVER (PARTITION BY Flat, YEAR)
       ) AS Cancel_ratio
FROM (SELECT r.*, EXTRACT(YEAR FROM pay_day) AS Year
      FROM `finances.reservations` r
     ) r
GROUP BY Flat, Year
ORDER BY 1

【讨论】:

这会导致以下错误:“PARTITION BY 表达式引用了在 [3] 处既未分组也未聚合的列 pay_day @Bran 。 . .根据您使用的数据库,您可能可以在那里使用year。您尚未指定数据库。 我在标题中说过,BigQuery 中使用的是标准 SQL 经过一些实验,这似乎是由于 USD_amt 是一个整数,我已经发布了代码和错误并相应地更改了标题。谢谢你的建议

以上是关于使用 CAST FLOAT64 时仍然收到被零除的错误的主要内容,如果未能解决你的问题,请参考以下文章

避免在 PostgreSQL 中被零除

Java中与&&不一致和被零除错误

除了被零除之外,还都有哪些情况会发生浮点异常?

我在python中得到“被零除”错误,但我不知道为什么

为啥这个 if 语句没有失败? [复制]

Jvm(44),指令集----运算指令