题目描述
(通过次数1,593 | 提交次数2,019,通过率78.90%)
?表名: Transactions +-------------+------+ | Column Name | Type | +-------------+------+ | account_id | int | | day | date | | type | ENUM | | amount | int | +-------------+------+ (account_id, day) 是该Transactions表的主键. 表中的每行数据表示一次交易的信息, 包括此次交易的账号(account_id), 交易类型(type), 交易发生时间(day), 交易发生金额(amount). 其中交易类型(type)字段包括了两种行为:存入 ('Deposit'), 取出('Withdraw'). 请写出能够返回用户每次交易完成后的账户余额. 我们约定所有用户在进行交易前的账户余额都为0,并且保证所有交易行为后的余额不为负数。 返回的结果请依次按照 账户(account_id),日期(day) 进行升序排序. 查询结果的格式请参照以下测试样例. 测试样例1: 输入: Transactions 表: +------------+------------+----------+--------+ | account_id | day | type | amount | +------------+------------+----------+--------+ | 1 | 2021-11-07 | Deposit | 2000 | | 1 | 2021-11-09 | Withdraw | 1000 | | 1 | 2021-11-11 | Deposit | 3000 | | 2 | 2021-12-07 | Deposit | 7000 | | 2 | 2021-12-12 | Withdraw | 7000 | +------------+------------+----------+--------+ 输出: +------------+------------+---------+ | account_id | day | balance | +------------+------------+---------+ | 1 | 2021-11-07 | 2000 | | 1 | 2021-11-09 | 1000 | | 1 | 2021-11-11 | 4000 | | 2 | 2021-12-07 | 7000 | | 2 | 2021-12-12 | 0 | +------------+------------+---------+ 解释: 账户1: - 初始金额为 0. - 2021-11-07 --> 存入2000. 余额变为 0 + 2000 = 2000. - 2021-11-09 --> 取出1000. 余额变为 2000 - 1000 = 1000. - 2021-11-11 --> 存入3000. 余额变为 1000 + 3000 = 4000. 账户2: - 初始金额为 0. - 2021-12-07 --> 存入7000. 余额变为 0 + 7000 = 7000. - 2021-12-12 --> 取出 7000. 余额变为 7000 - 7000 = 0. 来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/account-balance
//测试数据 Create table If Not Exists Transactions (account_id int, day date, type ENUM('Deposit', 'Withdraw'), amount int); insert into Transactions (account_id, day, type, amount) values ('1', '2021-11-07', 'Deposit', '2000'); insert into Transactions (account_id, day, type, amount) values ('1', '2021-11-09', 'Withdraw', '1000'); insert into Transactions (account_id, day, type, amount) values ('1', '2021-11-11', 'Deposit', '3000'); insert into Transactions (account_id, day, type, amount) values ('2', '2021-12-07', 'Deposit', '7000'); insert into Transactions (account_id, day, type, amount) values ('2', '2021-12-12', 'Withdraw', '7000');
解题思路
这是一个典型的使用开窗函数实现累计统计的题目。
题目要求按账户每天累计,所以需要使用account_id开窗。
因为是按天从小到大累计,所以需要按day排序。
最后,因为要求进行累计求和计算,所以可以使用sum函数。
但这里不能直接对amount进行累计,因为当交易类型为取出时,需要对余额进行扣减而不是增加。所以,在sum函数中,需要根据交易类型对amount进行处理。
参考SQL
未特别说明的情况下,参考SQL为基于MySQL8.0实现。
select account_id, day, sum(case when type = 'Deposit' then amount else -1 * amount end) over(partition by account_id order by day) balance from Transactions order by account_id, day;
本站所有内容均为原创,本站保留所有权利。仅允许非商业用途的转载,但必须注明来源网站、作者、来源链接!否则,由此造成的一切后果,由转载方承担!
干货分享、技术提升、面试笔试、学习交流,欢迎关注公众号:xuesql。QQ学习交流群:209942678。