如何获取某个日期前的最新余额(t-sql)
How to get the latest balance before a certain date (t-sql)
我 运行 遇到一个问题,我试图在 2020 年 4 月 30 日之前获得最新余额。
Table Customer
有以下列:
CustomerId, CustomerName, CustomerCity, CustomerCurrentBalance.
Table 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
这里的问题是我在这个日期之前得到了所有 t运行sactions。但我需要这个日期之前的最后一个,因为它是最新的,我必须将其显示为按 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
您可以使用 row_number() window 函数 查找每个客户的最新行:
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
另请注意如何使用 别名 使查询更紧凑且更易于阅读。
我 运行 遇到一个问题,我试图在 2020 年 4 月 30 日之前获得最新余额。
Table Customer
有以下列:
CustomerId, CustomerName, CustomerCity, CustomerCurrentBalance.
Table 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
这里的问题是我在这个日期之前得到了所有 t运行sactions。但我需要这个日期之前的最后一个,因为它是最新的,我必须将其显示为按 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
您可以使用 row_number() window 函数 查找每个客户的最新行:
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
另请注意如何使用 别名 使查询更紧凑且更易于阅读。