如何在Google BigQuery中计算每月首尾日Value1差值及Value2最大值?
同一查询完成两项统计任务更高效
完全可以在同一查询里完成这两个需求,而且比分开写两个查询更简便——既减少了数据扫描的开销,代码也更简洁易维护。
核心思路
利用分组聚合(或结合窗口函数),在一次遍历数据集的过程中同时计算两个统计值:
- 对于
Value1的月末与月初差值:因为你明确说明Value1全月递增,所以当月最后一天的Value1就是当月最大值,第一天的是当月最小值,直接用MAX(Value1) - MIN(Value1)就能得到差值;如果要严格匹配第一天和最后一天的记录,也可以用窗口函数提取对应值再计算。 - 对于
Value2的当月最大值:直接用MAX(Value2)聚合即可。
示例SQL代码(以MySQL为例)
方法1:利用Value1递增特性简化计算
SELECT ID, DATE_FORMAT(Timestamp, '%Y-%m') AS month, MAX(Value1) - MIN(Value1) AS value1_monthly_diff, MAX(Value2) AS value2_monthly_max FROM your_table GROUP BY ID, DATE_FORMAT(Timestamp, '%Y-%m');
方法2:严格匹配第一天和最后一天的记录(适用于非递增场景)
如果后续Value1规则变化,或者需要精准取首尾日数据,可以用窗口函数:
WITH daily_stats AS ( SELECT ID, DATE_FORMAT(Timestamp, '%Y-%m') AS month, Value1, Value2, -- 提取当月第一天的Value1 FIRST_VALUE(Value1) OVER (PARTITION BY ID, month ORDER BY Timestamp) AS first_day_val1, -- 提取当月最后一天的Value1 LAST_VALUE(Value1) OVER (PARTITION BY ID, month ORDER BY Timestamp ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_day_val1 FROM your_table ) SELECT ID, month, last_day_val1 - first_day_val1 AS value1_monthly_diff, MAX(Value2) AS value2_monthly_max FROM daily_stats GROUP BY ID, month, first_day_val1, last_day_val1;
为什么不分开写查询?
- 性能更优:分开写两个查询需要两次扫描整个数据集,同一查询只需要一次,数据量越大,差异越明显。
- 代码更简洁:把两个统计逻辑整合在一起,后续修改或维护只需要操作一处。
内容的提问来源于stack exchange,提问作者DCBengals
相关产品推荐
相关产品推荐

