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

Spark ANSI SQL:按状态A划分区间计算金额总和

问题描述

现有一张结构如下的表(假设表名为transactions):

amountstatustimestamp
10A0
10B1
15B2
10C3
12D4
20A5
25B6
17C7
19D8

其中amount为数值类型,status字段允许重复。需求是计算每两个相邻状态'A'之间所有记录的amount总和,预期结果如下:

sumtimestamp
571
815
兼容Spark的ANSI SQL实现方案

通过窗口函数标记分组后聚合计算,具体SQL如下:

WITH a_markers AS (
    SELECT 
        *,
        -- 累计统计当前行及之前的A状态数量,作为分组ID
        SUM(CASE WHEN status = 'A' THEN 1 ELSE 0 END) OVER (ORDER BY timestamp) AS group_id
    FROM transactions
),
grouped_sums AS (
    SELECT 
        group_id,
        SUM(amount) AS total_sum,
        -- 取分组内第一条非A记录的timestamp
        MIN(CASE WHEN status != 'A' THEN timestamp END) AS result_timestamp
    FROM a_markers
    GROUP BY group_id
    -- 过滤仅包含A状态的分组
    HAVING result_timestamp IS NOT NULL
)
SELECT 
    total_sum AS sum,
    result_timestamp AS timestamp
FROM grouped_sums;

逻辑说明

  1. 标记分组:利用窗口函数SUM(CASE...) OVER (ORDER BY timestamp),每遇到一条状态为'A'的记录,分组ID就递增,这样两个相邻'A'之间的所有记录会被归入同一分组。
  2. 分组聚合:按group_id分组后,计算每组amount的总和,同时提取组内第一条非'A'记录的timestamp,匹配预期结果的格式。
  3. 过滤无效分组:通过HAVING子句排除仅包含'A'状态的分组(比如最后一个'A'之后无其他记录的情况)。

结果验证

执行上述SQL后会得到预期结果:

  • 分组1包含timestamp 0-4的记录,总和为10+10+15+10+12=57,对应timestamp=1;
  • 分组2包含timestamp 5-8的记录,总和为20+25+17+19=81,对应timestamp=5。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 00:41:59