当前位置: 首页 > article >正文

计算帐户每月余额,补齐缺失日期:从 SQL 到 SPL

MSSQL 数据库有个资产账户的流水表,日期不连续。

NameDateDebitCredit
A2021-01-01100
A2021-01-0190
A2021-02-01110
A2021-03-01050
A2021-04-01300
B2021-01-01100
B2022-02-01012
B2022-03-01050
B2024-04-0130

现在要统计从期初 2021 年 1 月到期末 2024 年 4 月每个账户每个月的余额,缺失的月份要补齐。

NameymBlance
A20211-19
A20212-30
A2021320
A20214-10
A20215-10
A20243-10
A20244-10
B20211-10
B20212-10
B20221-10
B202222
B2022352
B2022452
B2024352
B2024449

SQL 解法:

WITH Accounts AS (
    SELECT DISTINCT Name FROM trans
),
Months AS (
    SELECT DATEADD(MONTH, n, '2021-01-01') AS MonthStart
    FROM (
        SELECT TOP (DATEDIFF(MONTH, '2021-01-01', '2024-04-01') + 1) 
        ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1 AS n
        FROM master.dbo.spt_values
    ) AS Numbers
),
AccountMonths AS (
    SELECT a.Name, m.MonthStart
    FROM Accounts a
    CROSS JOIN Months m
),
Changes as (
    SELECT Name, DATEADD(MONTH, DATEDIFF(MONTH, 0, Date), 0) as ym,
    sum(Credit - Debit) as change 
    FROM trans group by Name, DATEADD(MONTH, DATEDIFF(MONTH, 0, Date), 0)
),
fullChanges as (
    SELECT A.Name,A.MonthStart,c.change 
    FROM AccountMonths a left join Changes c 
    on a.Name=c.Name and a.MonthStart=c.ym
)
SELECT 
   Name,YEAR(MonthStart) AS Y,MONTH(MonthStart) AS M,
   SUM(change) OVER (PARTITION BY Name ORDER BY MonthStart) AS balance
   FROM fullChanges

SQL没有方便的方法生成月份序列,要用嵌套查询+窗口函数,代码非常复杂。

SPL提供了生成日期序列的函数,包括连续月份。

 A
1=mssql.query("select Name, DATEADD(MONTH, DATEDIFF(MONTH, 0, Date), 0)as ym,sum(Credit - Debit) as change from trans group by Name, DATEADD(MONTH, DATEDIFF(MONTH, 0, Date), 0)”)
2=periods@m(date("2021-01-01"),date("2024-04-01"),1)
3=xjoin(A1.id(Name):Name; A2:ym)
4=A3.join(Name:ym, A1:Name:ym,change)
5=A4.new(Name,year(ym):y,month(ym):m,change+if(Name==Name[-1] , Balance[-1]):Balance)

A1:查询数据库,按账户、每月第1天的日期分组,统计每月金额变化。

A2:生成每月第一天组成的连续序列。perionds生成日期序列,@m表示间隔单位为月份。

A3:将账户和日期序列进行叉乘。

A4:将叉乘结果和A1左关联。

A5:当前账号与上一条记录相比不变时,当月余额=当月金额变化+上个月的余额;账号变化时,当月余额重置为当月金额变化。

SPL已开源免费,欢迎前往乾学院了解更多!

源码地址

免费下载


http://www.kler.cn/a/465291.html

相关文章:

  • ABAP 两个内表不同名称字段赋值的方法
  • JAVA类和对象练习
  • Fabric链码部署测试
  • vite-plugin-imagemin安装问题
  • 领域驱动设计(4)—绑定模型与实现
  • Pytorch的自动求导模块
  • Luma AI 简单几步生成视频
  • SpringMVC(一)配置
  • 【OpenCV】使用Python和OpenCV实现火焰检测
  • Spring Boot 中 TypeExcludeFilter 的作用及使用示例
  • 数据挖掘——聚类
  • vue3基础,小白从入门到精通
  • 三维算法基础知识
  • Unity Shader:从基础使用到动画实现全解析
  • 二层交换机和三层交换机
  • Vue3+Vue-router(history+路由前缀)+Vite 下本地刷新找不到页面问题
  • 钉钉h5微应用引用钉钉文件地址
  • 解决MYSQL Table has no partition for value from column_list的问题
  • jenkins修改端口以及开机自启
  • Kafka和Jenkins实现EMR上PySpark和EC2上Airflow的CI/CD
  • tcpdump的常见方法
  • Matlab中文注释乱码
  • 力扣编程从0-1
  • Elasticsearch JavaRestClient版
  • SQL 中索引分析,查询表索引
  • 滑雪护目镜欧盟CE认证EN 174测试标准