You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Standard SQL如何实现月度数据按每3个月动态分组统计?

实现方案

你可以基于现有逻辑扩展,先补全缺失月份再按3个月分组聚合即可,完整修改后的SQL如下:

WITH utils AS (
    SELECT
        today,
        month_lag,
        GENERATE_DATE_ARRAY(DATE_SUB(DATE_TRUNC(DATE_SUB(today, INTERVAL month_lag MONTH), MONTH), INTERVAL 11 MONTH), DATE_TRUNC(DATE_SUB(today, INTERVAL month_lag MONTH), MONTH), INTERVAL 1 MONTH) AS months
    FROM (
        SELECT
            CURRENT_DATE() AS today,
            IF(EXTRACT(DAY FROM CURRENT_DATE()) < 7, 2, 1) AS month_lag
    )
),
-- 原有按月聚合结果
monthly_stats AS (
    SELECT
        date,
        MAX(ndays) AS ndays,
        COUNT(*) AS count
    FROM (
        SELECT
            DATE_TRUNC(date, MONTH) AS date,
            IFNULL(DATE_DIFF(date, prev_date, DAY), 186) AS ndays
        FROM (
            SELECT
                date,
                LAG(date, 1) OVER (ORDER BY date) AS prev_date
            FROM `myproject.mydataset.mytable`, utils
            WHERE
                DATE_TRUNC(date, MONTH) >= DATE_TRUNC(DATE_SUB(today, INTERVAL 17+month_lag MONTH), MONTH)
                AND type = 'Departamento'
        ), utils
        WHERE DATE_TRUNC(date, MONTH) BETWEEN DATE_TRUNC(DATE_SUB(today, INTERVAL 11+month_lag MONTH), MONTH) AND DATE_TRUNC(DATE_SUB(today, INTERVAL month_lag MONTH), MONTH)
    )
    GROUP BY date
),
-- 补全所有月份,关联已有统计数据并生成分组编号
full_months AS (
    SELECT
        m.month AS date,
        IFNULL(s.ndays, 0) AS ndays,
        IFNULL(s.count, 0) AS count,
        -- 自动计算分组号:每3个连续月份为一组
        DIV(DATE_DIFF(m.month, MIN(m.month) OVER(), MONTH), 3) AS group_id
    FROM utils, UNNEST(utils.months) AS m
    LEFT JOIN monthly_stats s ON m.month = s.date
)
-- 最终按分组聚合得到目标结果
SELECT
    CONCAT(FORMAT_DATE("%Y %B", MIN(date)), " - ", FORMAT_DATE("%Y %B", MAX(date))) AS group_name,
    MAX(ndays) AS ndays,
    SUM(count) AS count,
    SUM(32 - EXTRACT(DAY FROM DATETIME_ADD(DATETIME_TRUNC(DATETIME_SUB(date, INTERVAL 1 MONTH), MONTH), INTERVAL 31 DAY))) AS group_ndays
FROM full_months
GROUP BY group_id
ORDER BY group_id

关键逻辑说明

  • 通过UNNEST(utils.months)展开预先生成的完整月份数组,左关联原有按月统计结果,补全缺失月份的统计值为0,避免缺失月份导致分组偏移
  • 使用DIV(DATE_DIFF(m.month, MIN(m.month) OVER(), MONTH), 3)自动分配分组编号,无需硬编码分组范围,可适配任意统计区间的自动分组
  • 聚合时通过FORMAT_DATE格式化月份名称拼接分组名,同时按提供的公式累加计算分组总天数

注:你给出的期望输出示例中的分组年份存在笔误,实际执行后第二组会显示为2021 January - 2021 March,符合真实时间范围。

内容的提问来源于stack exchange,提问作者Luiscri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 12:06:03