【问题标题】:How to get the latest balance before a certain date (t-sql)如何获取某个日期之前的最新余额(t-sql)
【发布时间】:2021-12-20 03:23:54
【问题描述】:

我遇到了一个问题,我试图在 2020 年 4 月 30 日之前获得最新余额。

Customer 具有以下列:

CustomerId, CustomerName, CustomerCity, CustomerCurrentBalance. 

Customer_Transaction_Entry 具有以下列:

TransactionNumber, CustomerId, Country, Created, Amount, Details, Balance

这是我目前的查询:

select 
    dbo.Customer_Transaction_Entry.CustomerId,  
    dbo.Customer_Transaction_Entry.Country, 
    dbo.Customer_Transaction_Entry.Balance
from 
    dbo.Customer_Transaction_Entry
join
    dbo.Customer on Customer.CustomerId = Customer_Transaction_Entry.CustomerId
where 
    Customer_Transaction_Entry.Created < '2020-04-30'
order by 
    CustomerId

这里的问题是我在此日期之前获得了所有交易。但我需要此日期之前的最后一个,因为它是最新的,我必须将其显示为按 BalanceDate 分组的客户的当前余额。

这是 dbo.Customer_Transaction_Entry 的示例数据:

TransactionNo CustomerId Country Created Amount Details Balance
10001   1   Country1    2020-01-01  80.000000   Purchase    80.000000
10002   1   Country1    2020-02-06  20.000000   Payment 60.000000
10003   1   Country1    2020-02-06  120.000000  Purchase    180.000000
10004   1   Country1    2020-02-23  20.000000   Payment 160.000000
10005   1   Country1    2020-04-06  20.000000   Payment 140.000000
10006   1   Country1    2020-05-06  120.000000  Purchase    260.000000
10007   1   Country1    2020-06-23  20.000000   Payment 240.000000
10008   4   Country1    2020-01-01  80.000000   Purchase    80.000000
10009   4   Country1    2020-02-06  20.000000   Payment 60.000000
10010   4   Country1    2020-02-06  120.000000  Purchase    180.000000
10011   4   Country1    2020-02-23  20.000000   Payment 160.000000
10012   4   Country1    2020-04-06  20.000000   Payment 140.000000
10013   4   Country1    2020-06-23  20.000000   Payment 248.000000
10014   21  Country2    2020-01-01  80.000000   Purchase    80.000000
10015   21  Country2    2020-02-06  20.000000   Payment 60.000000
10016   21  Country2    2020-02-06  120.000000  Purchase    180.000000
10017   21  Country2    2020-02-23  20.000000   Payment 160.000000
10018   21  Country2    2020-05-09  20.000000   Payment 140.000000
10019   21  Country2    2020-05-09  142.000000  Purchase    282.000000
10020   21  Country2    2020-07-23  20.000000   Payment 262.000000
10023   4   Country1    2020-04-06  128.000000  Purchase    268.000000

对于较小的 dbo.Customer:

CustomerId CustomerName CustomerCity CustomerCurrentBalance
1      CustomerName1    CustomerCity    NULL
2      CustomerName2    CustomerCity    NULL
3       CustomerName3   CustomerCity    NULL
4       CustomerName4   CustomerCity    NULL
6       CustomerName6   CustomerCity    NULL
13      CustomerName13  CustomerCity    NULL
21     CustomerName21   CustomerCity    NULL
22     CustomerName22   CustomerCity    NULL
23      CustomerName23  CustomerCity    NULL

期望的结果应该是:

BalanceDate CustomerId Country   Balance

2020-04-30   1         Country1  140
2020-04-30   4         Country1  268
2020-04-30   21        Country2  160

【问题讨论】:

标签: sql-server tsql ssms


【解决方案1】:

您可以使用 row_number() 窗口函数查找每个客户最近的行:

with t as (
  select t.created as BalanceDate, t.CustomerId, t.Country, t.Balance,
    Row_Number() over(partition by t.CustomerId order by t.TransactionNo desc) rn
  from dbo.Customer c
  join dbo.Customer_Transaction_Entry t on t.CustomerId = c.CustomerId
  where t.Created < '20200430'
)
select BalanceDate, CustomerId, Country, Balance
from t
where rn=1

还要注意使用 aliases 如何使查询更紧凑、更易于阅读。

【讨论】:

  • 非常接近解决方案,但在其中一位客户 4 上,即使在此日期之前,也没有出现最新交易。我希望我可以在这里发布一些照片作为示例,但是我不允许我在这里上传任何东西。此外,我必须将表 Customer_Transaction_Entry 中的最新余额更新为 Customer 表中的 CustomerCurrentBalance 列,其中最初 CustomerCurrentBalance 都是 NULL
  • @MertKarakas 你不需要发布任何照片。如果没有样本数据,上述内容自然未经测试。如果您将示例数据和所需结果作为文本添加到您的问题中,它将使提供工作解决方案变得更加容易和清晰,请参阅Minimal, Reproducible Example
  • 我已添加示例数据
  • @MertKarakas 查看您的示例数据,除非您只是在输出中硬编码,否则我看不出您的 30/04 日期来自哪里?但是,我对上述内容进行了细微调整,它确实为您的 customerId 1、4、21 返回了 3 行。
猜你喜欢
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-18
  • 2020-08-12
  • 1970-01-01
  • 1970-01-01
  • 2011-04-26
相关资源
最近更新 更多