sql - 为什么 GROUP BY 的 BigQuery COUNT(*) 不正确?
问题描述
我有一个带有唯一整数ID
和AuditUpdated
时间戳的表。我试图将其按ID
范围划分为记录组,如下所示:
SELECT CAST(ID / 100000 AS INT64) AS `Start`,
COUNT(*) AS `RowCount`,
MAX(AuditUpdated) AS `LastMod`
FROM `dataset.mytable`
GROUP BY `Start`
ORDER BY `Start`
这似乎有效,前 3 条记录我得到以下信息:
0, 25526, 2016-03-29 15:32:11.473 UTC
1, 65892, 2017-11-22 20:05:38.800 UTC
2, 48550, 2017-12-23 01:03:25.030 UTC
然而,COUNT(*)
这里是错误的。例如,我可以运行以下命令:
SELECT COUNT(*) FROM `dataset.mytable` WHERE ID < 100000
结果是61989
!不仅如此,MAX(AuditUpdated)
实际上是2017-03-30 22:47:19.153 UTC
。
我对 Microsoft SQL Server 数据库中的同一个表运行相同的查询,它工作正常。我只能假设 BigQuery 以不同的方式做事,但我终生无法弄清楚如何做!
解决方案
在 BigQuery 中运行这个玩具示例:
select
cast(x/10 as int64) as bucket,
min(x) as min_x,
max(x) as max_x
from unnest(generate_array(1,1000,1)) x
group by 1
在SQL Server中, anINT/INT
执行“整数除法”,它返回结果的整个整数部分并丢弃余数/小数位(也就是向下舍入)。跑步select 5/3
应该返回1
而不是1.666667~
说明这一点。
另一方面,BigQueryFLOAT64
在划分时返回 aINT64/INT64
如 BigQuery StandardSQL Documentation中所述,将 aFLOAT64
转换为INT64
“返回最接近的 INT64 值”(又名正常舍入)。您的1
存储桶实际上正在计算 和 之间的所有50000
ID 149999
。
如果您想复制 SQL Server 逻辑,请考虑对您的 BigQuery 代码进行以下编辑:CAST(FLOOR(ID / 100000) AS INT64)
.
推荐阅读
- android - 为什么有2个HorizontalGridView时焦点没有改变
- python - 如何根据数据集的平均值缩小/缩放一个点?
- php - 当在函数中设置变量时,如何让 SESSION 变量工作?未设置显示索引
- c# - Canvas 落后于内容控制
- node.js - app engine deploy with [13] Error processing user code
- python-3.x - 如何使用 selenium webdriver 单击此按钮?
- python - 如何从路径运行 python 脚本,同时包含 .txt 等额外文件
- django - Django:用户的对等身份验证失败
- python - 如何让 Keras CNN 使用正确数量的维度?
- ios - 有没有办法在没有 AppStore 的情况下更新 iOS 应用程序?