我正在尝试使用 BQ 中的两个表创建表格报告。一张表是包含合同开始日期、名称和期初余额的合同列表。另一个是这些合约中发生的交易列表(与合约的多对一关系 t.contract_name = c.name)。
我遇到的问题是基于获取每季度的期初和期末余额(首选财务季度)。
我在 mysql 中使用了一个小提琴,因为 BQ 没有太大不同: https://www.db-fiddle.com/f/dXV1oLCgsS8ptAGYrjFmCX/0
本质上,我需要的是:合同名称,日期(例如以FY23-24Q1的形式汇总),该季度的期初余额,预付款总额,付款总额,总额版税,该季度的期末余额。
我假设我需要使用合约期初余额作为第一个可能的余额,然后每个后续期初余额都是上一季度的期末余额。
我希望能够将此数据加载到 Tableau 之类的工具中,以便我可以为用户提供筛选器,而不是在 BQ 中对数据本身执行合同/日期筛选。这看起来很简单,但每次我尝试它时,我最终都会陷入循环,其中期初余额依赖于期末余额或创建无尽的 CTE 或我对给定季度的所有期初余额而不是第一个余额求和的情况。
当一个季度的同一天有多个交易时,这也需要起作用(因为我也遇到了这个问题)。
在这个查询中,我认为它给了你你想要的。 这里的问题是,由于我没有合同创建日期,所以我只是使用任意值“2023-01-01”来生成每个季度的日期数组。
with
contract as
(
select "Robin" as name, 50 as opening_balance union all
select "James" as name, 150 as opening_balance
),
transactions as
(
select "James" as contract_name, -50 amount, "Advance" as type, date '2023-01-04' as _date union all
select "James" as contract_name, -50 amount, "Payment" as type, date '2023-03-04' as _date union all
select "James" as contract_name, -50 amount, "Payment" as type, date '2023-05-04' as _date union all
select "James" as contract_name, 50 amount, "Royalties" as type, date '2023-09-04' as _date union all
select "James" as contract_name, 50 amount, "Royalties" as type, date '2023-11-04' as _date
),
trx_quarter as
(
select
contract_name as name,
date_trunc(_date, quarter) as quarter,
sum(amount) as amount,
from transactions
group by 1,2
)
select
name,
quarter,
opening_balance as initial_balance,
opening_balance + coalesce(sum(coalesce(amount, 0)) over (partition by name order by quarter rows between unbounded preceding and 1 preceding), 0) as opening_balance,
coalesce(amount, 0) as change_amount,
opening_balance + sum(coalesce(amount, 0)) over (partition by name order by quarter) as end_balance,
from contract as c
join unnest(generate_date_array("2023-01-01", current_date, interval 3 month)) as quarter
left join trx_quarter
using(name, quarter)