Sql server 我想找到每个帐户在某个日期之前的最后一笔交易
我有一个表(在Azure SQL Server上)定义如下:Sql server 我想找到每个帐户在某个日期之前的最后一笔交易,sql-server,select,group-by,flask-sqlalchemy,top-n,Sql Server,Select,Group By,Flask Sqlalchemy,Top N,我有一个表(在Azure SQL Server上)定义如下: CREATE TABLE dbo.[transaction] ( id INT IDENTITY(1,1) NOT NULL, [date] DATETIME NULL, amount FLOAT NULL, balance FLOAT NULL, account_id INT NULL, CONSTRAINT PK__transact__32F PRIMARY KEY (id) )
CREATE TABLE dbo.[transaction]
(
id INT IDENTITY(1,1) NOT NULL,
[date] DATETIME NULL,
amount FLOAT NULL,
balance FLOAT NULL,
account_id INT NULL,
CONSTRAINT PK__transact__32F PRIMARY KEY (id)
)
我想找出每个帐户在某个日期之前的最后余额。我需要返回的列有:帐户id、日期、余额
我试过:
select account_id, max(date) as date
from dbo.[transaction]
group by account_id
这是可行的,但不会返回余额
其次,我的交易首先按日期排序,然后按id排序。因此,如果在最长日期发生多笔交易,它应该选择id最高的交易的余额
我的应用程序是用flask sqlalchemy编写的,所以sqlalchemy的答案很好,但我也很乐意用SQL来回答。您可以使用
行数
windows函数为每个帐户id的行数,并为每个帐户取最后一行:
SELECT account_id, [date], balance
FROM (SELECT account_id, [date], balance,
ROW_NUMBER() OVER (PARTITION BY account_id
ORDER BY [date] DESC, id DESC) AS rn
FROM [transaction]) t
WHERE rn = 1
您可以使用
row\u number
windows函数为每个帐户id的行编号,并为每个帐户取最后一行:
SELECT account_id, [date], balance
FROM (SELECT account_id, [date], balance,
ROW_NUMBER() OVER (PARTITION BY account_id
ORDER BY [date] DESC, id DESC) AS rn
FROM [transaction]) t
WHERE rn = 1
解决方案:包括您的日期检查
CREATE TABLE #transaction (
id int NOT NULL,
[date] datetime NULL,
amount float NULL,
balance float NULL,
account_id int NULL
) ;
Insert Into #transaction Values
(1,'2018-11-20',50,4000,100),
(2,'2018-11-21',75,2475,100),
(3,'2018-12-15',75,2400,100),
(4,'2018-11-22',25,4000,200),
(5,'2018-11-22',25,4000,300)
With CTE As
(
Select
ROW_NUMBER() Over(Partition By account_id Order By [Date] Desc) As rn,
account_id, [Date], balance
From #transaction
Where [Date] < '2018-12-01'
)
Select account_id, [Date], balance From CTE
Where rn = 1
解决方案:包括您的日期检查
CREATE TABLE #transaction (
id int NOT NULL,
[date] datetime NULL,
amount float NULL,
balance float NULL,
account_id int NULL
) ;
Insert Into #transaction Values
(1,'2018-11-20',50,4000,100),
(2,'2018-11-21',75,2475,100),
(3,'2018-12-15',75,2400,100),
(4,'2018-11-22',25,4000,200),
(5,'2018-11-22',25,4000,300)
With CTE As
(
Select
ROW_NUMBER() Over(Partition By account_id Order By [Date] Desc) As rn,
account_id, [Date], balance
From #transaction
Where [Date] < '2018-12-01'
)
Select account_id, [Date], balance From CTE
Where rn = 1
提供的两个答案同样精彩 我已将其转换为python sqlalchemy答案以供参考:
from sqlalchemy import func
from datetime import datetime
import pandas as pd
start = datetime(2018,12,1)
row_number_column = func.row_number() \
.over(partition_by=Transaction.account_id,
order_by=(Transaction.date.desc(), Transaction.id.desc())) \
.label('row_number')
query = DB.session.query(
Transaction.account_id,
Transaction.date,
Transaction.balance,
row_number_column) \
.filter(Transaction.date < start) \
.from_self().filter(row_number_column == 1)
df = pd.DataFrame(query.all(), columns=['Account Id', 'Date', 'Balance', 'RowId'])
df.drop(['RowId'], axis=1, inplace=True)
print(df)
来自sqlalchemy导入函数
从日期时间导入日期时间
作为pd进口熊猫
开始=日期时间(2018,12,1)
行数列=函数行数()\
.over(partition\u by=Transaction.account\u id,
order_by=(Transaction.date.desc(),Transaction.id.desc())\
.标签(“行号”)
query=DB.session.query(
Transaction.account\u id,
交易日期,
交易余额,
行(数字列)\
.filter(Transaction.date
最后三个可选行将其转换为一个包含期初余额的数据框,按日期和id排序。提供的两个答案同样精彩 我已将其转换为python sqlalchemy答案以供参考:
from sqlalchemy import func
from datetime import datetime
import pandas as pd
start = datetime(2018,12,1)
row_number_column = func.row_number() \
.over(partition_by=Transaction.account_id,
order_by=(Transaction.date.desc(), Transaction.id.desc())) \
.label('row_number')
query = DB.session.query(
Transaction.account_id,
Transaction.date,
Transaction.balance,
row_number_column) \
.filter(Transaction.date < start) \
.from_self().filter(row_number_column == 1)
df = pd.DataFrame(query.all(), columns=['Account Id', 'Date', 'Balance', 'RowId'])
df.drop(['RowId'], axis=1, inplace=True)
print(df)
来自sqlalchemy导入函数
从日期时间导入日期时间
作为pd进口熊猫
开始=日期时间(2018,12,1)
行数列=函数行数()\
.over(partition\u by=Transaction.account\u id,
order_by=(Transaction.date.desc(),Transaction.id.desc())\
.标签(“行号”)
query=DB.session.query(
Transaction.account\u id,
交易日期,
交易余额,
行(数字列)\
.filter(Transaction.date
最后三个可选行将其转换为具有期初余额的pandas数据框,按日期排序,然后按id排序。这已被询问和回答数百次,如果不是数千次的话。您使用按帐户id划分的行数。旁注:对于任何需要精确的数字,我建议不要使用
FLOAT
,尤其是涉及金钱的数字FLOAT
天生容易出现舍入错误-我建议使用DECIMAL(p,s)
来代替它,事实上它是精确的Hanks marc_s,这很好知道!这已经被问了几百次,甚至几千次了。您使用按帐户id划分的行数。旁注:对于任何需要精确的数字,我建议不要使用FLOAT
,尤其是涉及金钱的数字FLOAT
天生容易出现舍入错误-我建议使用DECIMAL(p,s)
来代替它,事实上它是精确的Hanks marc_s,这很好知道!明亮的正是我想要的。老实说,我不知道另一种方法的行数是否更适合我的场景,尤其是在两个不同字段上排序时。你的答案最终在如何使用行数分区上大赚了一笔!明亮的正是我想要的。老实说,我不知道另一种方法的行数是否更适合我的场景,尤其是在两个不同字段上排序时。你的答案最终在如何使用行数分区上大赚了一笔!很好的例子,带有日期检查和示例数据。如果可以的话,我想把这两个答案都标记为答案!很好的例子,带有日期检查和示例数据。如果可以的话,我想把这两个答案都标记为答案!