如何计算平均每日余额 - 当前周期

问题描述 投票:0回答:1

我有这些数据,我想计算, 平均每日余额 - 当前周期:1,595.49 美元。 我尝试平均中位数模式和手动总和/T行,但所有结果都不同

fd  tr_type amount  date            balance
8   credit  789.81  2/2/2024    789.81
8   credit  529.98  2/15/2024   1319.79
8   debit   29      2/15/2024   1290.79
8   debit   95.99   2/20/2024   1194.8
8   credit  1000    2/21/2024   2194.8
8   credit  494.12  2/22/2024   2688.92
8   debit   10      2/22/2024   2678.92
8   debit   1405    2/22/2024   1273.92
8   debit   15      2/23/2024   1258.92
8   credit  571     2/27/2024   1829.92
8   credit  533.8   2/29/2024   1258.92
8   credit  0.05    2/29/2024   1829.92
8   debit   123.07  3/6/2024    2240.7
8   debit   186.58  3/6/2024    2054.12
8   credit  516.4   3/7/2024    2570.52
8   debit   138.53  3/7/2024    2431.99
8   debit   510.23  3/8/2024    1921.76

然后我尝试按日期之间的天数计算每日余额*,然后 t 求和并除以月份天数,它给出的结果接近 99.9% 正确(0.03 的微小差异)

enter image description here

然后我使用这个mysql命令来实现上述方法。

WITH RECURSIVE date_range AS (
    -- Generate a sequence of dates
    SELECT MIN(t.date1) AS date1
    FROM transactions t
    WHERE t.fd = '8'
    UNION ALL
    SELECT DATE_ADD(date1, INTERVAL 1 DAY)
    FROM date_range
    WHERE DATE_ADD(date1, INTERVAL 1 DAY) <= (SELECT MAX(t.date1) FROM transactions t WHERE t.fd = '8')
),
daily_balances AS (
    -- Calculate daily balance
    SELECT 
        d.date1,
        SUM(
            CASE 
                WHEN t.transaction_type = 'credit' THEN t.amount 
                WHEN t.transaction_type = 'debit' THEN -t.amount 
                ELSE 0 
            END
        ) OVER (ORDER BY d.date1 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS balance
    FROM 
        date_range d
    LEFT JOIN transactions t ON d.date1 = t.date1 AND t.fd = '8'
)
-- Select the result to show balance for each day
SELECT 
    date1, 
    IFNULL(balance, LAG(balance) OVER (ORDER BY date1)) AS daily_balance
FROM 
    daily_balances
ORDER BY 
    date1 ASC;

它为我提供了每月所有天的每日余额,但我想要同一天的最后一行余额,并且我使用

ROW_NUMBER()
函数给出了错误的行号记录。

WITH RECURSIVE date_range AS (
    -- Generate a sequence of dates
    SELECT MIN(t.date1) AS date1
    FROM transactions t
    WHERE t.fd = '8'
    UNION ALL
    SELECT DATE_ADD(date1, INTERVAL 1 DAY)
    FROM date_range
    WHERE DATE_ADD(date1, INTERVAL 1 DAY) <= (SELECT MAX(t.date1) FROM transactions t WHERE t.fd = '8')
),
daily_balances AS (
    -- Calculate cumulative balance and rank transactions per day
    SELECT 
        d.date1,
        SUM(
            CASE 
                WHEN t.transaction_type = 'credit' THEN t.amount 
                WHEN t.transaction_type = 'debit' THEN -t.amount 
                ELSE 0 
            END
        ) OVER (ORDER BY d.date1 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS balance,
        ROW_NUMBER() OVER (PARTITION BY d.date1 ORDER BY t.id DESC) AS row_num -- Get the last balance of the day
    FROM 
        date_range d
    LEFT JOIN transactions t ON d.date1 = t.date1 AND t.fd = '8'
)
-- Select the last transaction of each day and carry over balance for days without transactions
SELECT 
    date1, 
    IFNULL(balance, LAG(balance) OVER (ORDER BY date1)) AS daily_balance
FROM 
    daily_balances
WHERE 
    row_num = 1 OR row_num IS NULL -- Select last balance for the day or null for days without transactions
ORDER BY 
    date1 ASC;

我想要平均每日余额 - 当前周期:1,595.49 美元。 我想我正在使用长期令人困惑的 mysql 查询。

如何针对这个特定案例编写查询?

sql mysql math stat banking
1个回答
0
投票

不太确定这种情况下的平均每日余额到底是多少。它是否包括没有交易的日期,您想要运行平均每日余额,或者,也许,每月???
不过,有一件事可以帮助您解决这个问题......

...但我想要同一天的最后一行余额...

WITH    --  Getting last balance of the day ordered per date by tr_type 
    day_balances AS
      ( Select    a.a_date, a.balance as day_balance
        From    ( Select    Row_Number() Over(Order By fd, a_date, tr_type) as rn, 
                            t.*, 
                            Row_Number() Over(Partition By fd, a_date Order By fd, a_date, tr_type) as a_date_rn,
                            Count(*) Over(Partition By fd, a_date) as a_date_count
                  From      tbl t
                ) a
        Where    a.a_date_rn = a.a_date_count
        Order By a.a_date
      )
Select * From day_balances Order By a_date;
/*    R e s u l t :  
a_date      day_balance
----------  -----------
2024-02-02       789.81
2024-02-15      1290.79
2024-02-20      1194.80
2024-02-21      2194.80
2024-02-22      1273.92
2024-02-23      1258.92
2024-02-27      1829.92
2024-02-29      1829.92
2024-03-06      2054.12
2024-03-07      2431.99
2024-03-08      1921.76      */

...相同的 cte (day_balances) 可用于获取每日平均值:

Select a_date, day_balance, 
       AVG(day_balance) Over(Order By a_date Rows Between Unbounded Preceding And Current Row) as AVG_so_far
From   day_balances
Order By a_date;
/*      R e s u l t :
a_date      day_balance       AVG_so_far
----------  -----------  ---------------
2024-02-02       789.81       789.810000
2024-02-15      1290.79      1040.300000
2024-02-20      1194.80      1091.800000
2024-02-21      2194.80      1367.550000
2024-02-22      1273.92      1348.824000
2024-02-23      1258.92      1333.840000
2024-02-27      1829.92      1404.708571
2024-02-29      1829.92      1457.860000
2024-03-06      2054.12      1524.111111
2024-03-07      2431.99      1614.899000
2024-03-08      1921.76      1642.795455    */

...或每月...

Select  DATE_FORMAT(a_date, '%Y-%m') as mnth,  
       AVG(day_balance) as AVG_month
From   day_balances
Group By DATE_FORMAT(a_date, '%Y-%m')
Order By DATE_FORMAT(a_date, '%Y-%m');
/*    R e s u l t : 
mnth       AVG_month
-------  -----------
2024-02  1457.860000
2024-03  2135.956667    */

请参阅此处的小提琴

© www.soinside.com 2019 - 2024. All rights reserved.