我在SQL中有一个包含日期和收入列的收入表.我想创建一个防止负收入值的逻辑,以便将任何负收入值设置为0,并从随后几个月的收入中减go 负金额,直到完全抵消为止.

例如,如果我有以下收入数据:

Date Revenue
2018-09-01 1200
2018-08-01 400
2018-07-01 -1000
2018-06-01 800
2018-05-01 600
2018-04-01 200
2018-03-01 -200
2018-02-01 400
2018-01-01 200

预期输出应为:

Date Revenue
2018-09-01 600
2018-08-01 0
2018-07-01 0
2018-06-01 800
2018-05-01 600
2018-04-01 0
2018-03-01 0
2018-02-01 400
2018-01-01 200

下面是一些入门代码


WITH revenue_table AS (
    SELECT '2018-09-01' AS date, 1200 AS revenue UNION ALL
    SELECT '2018-08-01' AS date, 400 AS revenue UNION ALL
    SELECT '2018-07-01' AS date, -1000 AS revenue UNION ALL
    SELECT '2018-06-01' AS date, 800 AS revenue UNION ALL
    SELECT '2018-05-01' AS date, 600 AS revenue UNION ALL
    SELECT '2018-04-01' AS date, 200 AS revenue UNION ALL
    SELECT '2018-03-01' AS date, -200 AS revenue UNION ALL
    SELECT '2018-02-01' AS date, 400 AS revenue UNION ALL
    SELECT '2018-01-01' AS date, 200 AS revenue
)

select * from revenue_table

我不知道该如何处理这个问题.有没有人能建议一个解决方案,或者提供一些实现这一逻辑的示例代码?

  • try 计算负值和减go 正值的滚动和
  • 递归,但看起来很慢,而且没有真正起作用

推荐答案

如果我没弄错的话,我们确实需要递归,这样我们就可以在以下各行迭代地分配负数.

对于这个算术,leastgreatest应该足够好了:

with recursive
    data as (
        select r.*, row_number() over(order by date) rn from revenue_table r
    ),
    rcte (date, old_revenue, rn, new_revenue, rest) as (
        select null::date, 0, 0::bigint, 0, 0
        union all
        select d.*, greatest(d.revenue + r.rest, 0), least(d.revenue + r.rest, 0)
        from rcte r
        inner join data d on d.rn = r.rn + 1
    )
select date, old_revenue, new_revenue 
from rcte 
where rn > 0 order by date desc
date old_revenue new_revenue
2018-09-01 1200 600
2018-08-01 400 0
2018-07-01 -1000 0
2018-06-01 800 800
2018-05-01 600 600
2018-04-01 200 0
2018-03-01 -200 0
2018-02-01 400 400
2018-01-01 200 200

fiddle

Sql相关问答推荐

使用`lag()`获取上一个时间戳

计算周时出现SQL错误结果

如何计算一个用户S的日常连胜?

NULL-生成的列中连接的字符串的输入

按日期时间(不包括秒)连接表

用户购买平台及金额统计

改进的SQL子字符串提取

最小非重复集的SQL查询

在SQL查询中查找客户端的最短日期比较列和多行

PostgreSQL中递归CTE查询的故障过滤

使用 union 的有序结果获取行数

SQL Server 查询 WHERE LIKE

SQL 查找 varchar 类型列及其值中多次出现的子字符串

Clickhouse:左连接表到外部数组

PostgreSQL如何将Unix纪元时间戳转换为日期时间并进行拼接

带聚合函数的 percentile_cont

joins 组合多个重复数据删除策略

来自 SQL Server 的树层次 struct 图的 JSON

SQL 计数和过滤查询优化

使用 SQL 表中的连接列删除重复记录