获取每个月的最后一行,如果未找到则获取上个月的最后一行

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

我有一个表

balance_history
,其结构和数据如下(简化)

账户 平衡 交易_日期
a 100 2024年9月29日
a 75 20/08/2024
a 65 2024年8月18日
b 50 2024年8月15日
c 200 2024年7月10日

仅当有交易时,账户余额才会出现在该表上。我可以通过对整个表运行 rank over partition 语句来获取每个帐户的当前/最新余额。

但是,我需要的是显示每个帐户的

每月

余额。这意味着,如果特定月份没有交易,我希望查询从前几个月开始搜索并找到具有最新余额的最后一笔交易(有 id 列)。 我想展示这个结果:

月07/202407/202407/202408/202408/202408/202409/202409/202409/2024
账户 平衡
a 0
b 0
c 200
a 75
b 50
c 200
a 100
b 50
c 200
如你所见,即使账户c在9月份没有交易,我仍然想显示余额。我怎样才能做到这一点?

sql oracle
1个回答
0
投票
PARTITION

ed

OUTER JOIN
将每月值加入日历:
WITH month_data (account, month, balance) AS (
  SELECT account,
         TRUNC(transaction_date, 'MM'),
         MAX(balance) KEEP (DENSE_RANK LAST ORDER BY Transaction_date)
  FROM   table_name t
  GROUP BY
         account,
         TRUNC(transaction_date, 'MM')
),
calendar (month) AS (
  SELECT ADD_MONTHS(min_month, LEVEL - 1)
  FROM   (
    SELECT MIN(month) AS min_month,
           MAX(month) AS max_month
    FROM   month_data
  )
  CONNECT BY ADD_MONTHS(min_month, LEVEL - 1) <= max_month
)
SELECT m.account,
       c.month,
       COALESCE(
         LAST_VALUE(m.balance) IGNORE NULLS
           OVER (PARTITION BY m.account ORDER BY c.month),
         0
       ) AS balance
FROM   calendar c
       LEFT OUTER JOIN month_data m
       PARTITION BY (m.account)
       ON c.month = m.month

对于样本数据:

CREATE TABLE table_name (Account, Balance, Transaction_date) AS SELECT 'a', 100, DATE '2024-09-29' FROM DUAL UNION ALL SELECT 'a', 75, DATE '2024-08-20' FROM DUAL UNION ALL SELECT 'a', 65, DATE '2024-08-18' FROM DUAL UNION ALL SELECT 'b', 50, DATE '2024-08-15' FROM DUAL UNION ALL SELECT 'c', 200, DATE '2024-07-10' FROM DUAL;

输出:

账户aaabbbccc
平衡
2024-07-01 00:00:00 0
2024-08-01 00:00:00 75
2024-09-01 00:00:00 100
2024-07-01 00:00:00 0
2024-08-01 00:00:00 50
2024-09-01 00:00:00 50
2024-07-01 00:00:00 200
2024-08-01 00:00:00 200
2024-09-01 00:00:00 200
小提琴

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