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

如何编写SQL实现impressions值在连续null行与非null行间均分?

问题描述

原始数据集

HOURAccount_idmedia_idimpressions
2022-11-04 04:00:00 UTC25678935null
2022-11-04 05:00:00 UTC25678935null
2022-11-04 06:00:00 UTC25678935null
2022-11-04 07:00:00 UTC25678935null
2022-11-04 08:00:00 UTC2567893540
2022-11-04 09:00:00 UTC256789357
2022-11-04 10:00:00 UTC25678935null
2022-11-04 11:00:00 UTC2567893510
2022-11-04 12:00:00 UTC2567893512

其中HOUR字段为无间隔的小时递增序列。

需求说明

当impressions字段值为null时,将后续第一个非null的impressions值均分到该段连续null行及此非null行本身:

  • 4个连续null行后是值为40的行,共5行,每行分配8;
  • 1个null行后是值为10的行,共2行,每行分配5。

已编写的部分SQL语句

select *,
      case when impressions is null then row_number() over(partition by media_id,ACCOUNT_ID ORDER BY HOUR) else 0 end as rn1,
from table_name order by 1 ;

预期输出

HOURAccount_idmedia_idimpressionsdistributed_impressions
2022-11-04 04:00:00 UTC25678935null8
2022-11-04 05:00:00 UTC25678935null8
2022-11-04 06:00:00 UTC25678935null8
2022-11-04 07:00:00 UTC25678935null8
2022-11-04 08:00:00 UTC25678935408
2022-11-04 09:00:00 UTC2567893577
2022-11-04 10:00:00 UTC25678935null5
2022-11-04 11:00:00 UTC25678935105
2022-11-04 12:00:00 UTC256789351212

解决方案SQL

完整代码

WITH step1 AS (
    SELECT 
        *,
        -- 标记每个待分配区间的分组ID
        SUM(CASE WHEN impressions IS NOT NULL THEN 1 ELSE 0 END) OVER (
            PARTITION BY media_id, account_id 
            ORDER BY hour 
            ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
        ) AS group_id
    FROM table_name
),
step2 AS (
    SELECT 
        *,
        -- 获取当前区间要分配的总impressions值
        LAST_VALUE(impressions IGNORE NULLS) OVER (
            PARTITION BY media_id, account_id, group_id 
            ORDER BY hour 
            ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
        ) AS total_impressions,
        -- 统计当前区间的总行数
        COUNT(*) OVER (
            PARTITION BY media_id, account_id, group_id
        ) AS group_row_count
    FROM step1
)
SELECT 
    hour,
    account_id,
    media_id,
    impressions,
    -- 计算均分后的值
    total_impressions / group_row_count AS distributed_impressions
FROM step2
ORDER BY hour;

逻辑解释

  1. step1:分组标记
    通过累加窗口函数,每遇到非null的impressions就累加1,把连续的null行和后续第一个非null行归为同一个group_id,实现区间划分。

  2. step2:计算区间参数

    • LAST_VALUE(impressions IGNORE NULLS):提取当前区间内最后一个非null的impressions值,也就是要均分的总数值。
    • COUNT(*) OVER (...):统计当前区间的总行数,作为均分的分母。
  3. 最终计算
    用区间总数值除以总行数,得到每行的分配值distributed_impressions。

这个方案无需依赖你之前编写的rn1字段,逻辑简洁且能覆盖所有符合需求的场景。

内容的提问来源于stack exchange,提问作者Teja Goud Kandula

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 23:25:34