从运行总计 (SQL) 雪花中排除某些记录

Posted

技术标签:

【中文标题】从运行总计 (SQL) 雪花中排除某些记录【英文标题】:Exclude certain records from running total (SQL) Snowflake 【发布时间】:2020-07-23 00:33:07 【问题描述】:

我有费用和预算表。不同的记录可能有不同的预算 如果超过记录中的预算,我不想增加运行总和。

就像分区中的总和大于预算一样,它停止增加,然后在预算更大时再次增加。

有可能吗?

create table spend 
(id number,
cents number,
budget number);

insert into spend(id,cents,budget) values(1,25,50);
insert into spend(id,cents,budget) values(2,25,50);
insert into spend(id,cents,budget) values(3,25,50);
insert into spend(id,cents,budget) values(4,25,50);
insert into spend(id,cents,budget) values(5,25,100);
insert into spend(id,cents,budget) values(6,25,100);
insert into spend(id,cents,budget) values(7,25,100);
insert into spend(id,cents,budget) values(8,25,200);
insert into spend(id,cents,budget) values(9,25,200);

这就是我得到的

vadimzilberleyb#TRANSFORM_WH@INSTADATA.DWH>select s.*, sum(cents) over(order by id)  from spend s;
+----+-------+--------+------------------------------+                          
| ID | CENTS | BUDGET | SUM(CENTS) OVER(ORDER BY ID) |
|----+-------+--------+------------------------------|
|  1 |    25 |     50 |                           25 |
|  2 |    25 |     50 |                           50 |
|  3 |    25 |     50 |                           75 |
|  4 |    25 |     50 |                          100 |
|  5 |    25 |    100 |                          125 |
|  6 |    25 |    100 |                          150 |
|  7 |    25 |    100 |                          175 |
|  8 |    25 |    200 |                          200 |
|  9 |    25 |    200 |                          225 |
+----+-------+--------+------------------------------+

这就是我想要的:)

id       cents  budget   cumul in run    cumulative desirable in run

1          25         50          25                 25
2.        25          50          50                 50
3          25         50          75                 50
4          25         50          100               50
5          25         100         125               75
6          25         100         150               100
7          25         100         175               100
8          25         200         200               125
9          25         200         225               150

【问题讨论】:

你知道预算是否总是会被击中吗? 并非总是如此。至少最大的可能不会 【参考方案1】:

这不能仅使用窗口函数来完成。您需要某种迭代过程来逐步决定当前的cents 是否应该添加到累积的sum 中。在 SQL 中,这通常通过递归查询来实现:

with 
    data as (
        select id, cents, budget, row_number() over(order by id) rn
        from spend
    ),
    rec as (
        select d.*, cents cumul from data d where rn = 1
        union all
        select 
            d.*, 
            case when r.cumul + d.cents > d.budget 
                then r.cumul 
                else r.cumul + d.cents 
            end
        from rec r
        inner join data d on d.rn = r.rn + 1
    )
select * from rec

如果id 总是从1 开始并且没有间隔地递增,那么你不需要第一个cte:

with rec as (
    select s.*, cents cumul from spend s where id = 1
    union all
    select 
        s.*, 
        case when r.cumul + s.cents > s.budget 
            then r.cumul 
            else r.cumul + s.cents 
        end
    from rec r
    inner join spend s on s.id = r.id + 1
)
select * from rec

Here is demo - 这是 SQL Server(因为在野外没有雪花小提琴),但语法应该同样适用于雪湖:

编号 |美分 |预算| rn |累积 -: | ----: | -----: | -: | ----: 1 | 25 | 50 | 1 | 25 2 | 25 | 50 | 2 | 50 3 | 25 | 50 | 3 | 50 4 | 25 | 50 | 4 | 50 5 | 25 | 100 | 5 | 75 6 | 25 | 100 | 6 | 100 7 | 25 | 100 | 7 | 100 8 | 25 | 200 | 8 | 125 9 | 25 | 200 | 9 | 150

【讨论】:

以上是关于从运行总计 (SQL) 雪花中排除某些记录的主要内容,如果未能解决你的问题,请参考以下文章

从雪花sql中的where子句中删除单引号

雪花; SQL 编译错误:无效的对象类型:GET_DDL 上的“EXTERNAL_TABLE”(“DATABASE”,“MyDb”)

雪花是不是支持 sql server 中使用的几何数据类型?

雪花任务正在执行,但在查询历史记录中找不到它们

预计将解析从 S3 加载的雪花数据中的列时到达记录末尾

雪花程序因任务执行而失败