Bank Account Summary II solution and explanation
9 more videos on this problem
LeetCode 1587 Interview SQL Question with Detailed Explanation | Practice SQLEveryday Data Science · 6:21 · 5K views
LeetCode 1587 - Bank Account Summary II - SQL SolutionNariman Alimuradov · 8:14 · 343 views
Bank Account Summary II (Leetcode 1587) in TeluguCoding Interview Preparation · 4:04 · 196 views
1587. Bank Account Summary 2 | LeetCode | SQL | Solution | Interview ProblemData Alchemist · 4:32 · 175 views
LeetCode || SQL Study Plan || Bank Account Summary II || Day 10BHAVESH HARIRAMANI · 3:36 · 72 views
LeetCode 1587 | Bank Account Summary II | Inner join | Group by | Having | SQLSleepy Cracker · 2:59 · 55 views
Bank Account Summary II #leetcode #mssqlserver #easyWinEi · 3:36 · 22 views
Leetcode 1587 Bank Account Summary IIDataWithAarish · 3:56 · 20 views
LeetCode 1587 | Bank Account Summary II | SQL Solution Explained | GROUP BY + HAVINGAbhishek Sakhare · 5:00 · 17 views
Leetcode 1587 Bank Account Summary II - SQL Interview Question - Explained In HindiAlgorithmicIQ · 9:11 · 10 views
The problem
Table: Users
+--------------+---------+ | Column Name | Type | +--------------+---------+ | account | int | | name | varchar | +--------------+---------+ account is the primary key (column with unique values) for this table. Each row of this table contains the account number of each user in the bank. There will be no two users having the same name in the table.
Table: Transactions
+---------------+---------+ | Column Name | Type | +---------------+---------+ | trans_id | int | | account | int | | amount | int | | transacted_on | date | +---------------+---------+ trans_id is the primary key (column with unique values) for this table. Each row of this table contains all changes made to all accounts. amount is positive if the user received money and negative if they transferred money. All accounts start with a balance of 0.
Write a solution to report the name and balance of users with a balance higher than 10000. The balance of an account is equal to the sum of the amounts of all transactions involving that account.
Return the result table in any order.
The result format is in the following example.
Example 1:
Input: Users table: +------------+--------------+ | account | name | +------------+--------------+ | 900001 | Alice | | 900002 | Bob | | 900003 | Charlie | +------------+--------------+ Transactions table: +------------+------------+------------+---------------+ | trans_id | account | amount | transacted_on | +------------+------------+------------+---------------+ | 1 | 900001 | 7000 | 2020-08-01 | | 2 | 900001 | 7000 | 2020-09-01 | | 3 | 900001 | -3000 | 2020-09-02 | | 4 | 900002 | 1000 | 2020-09-12 | | 5 | 900003 | 6000 | 2020-08-07 | | 6 | 900003 | 6000 | 2020-09-07 | | 7 | 900003 | -4000 | 2020-09-11 | +------------+------------+------------+---------------+ Output: +------------+------------+ | name | balance | +------------+------------+ | Alice | 11000 | +------------+------------+ Explanation: Alice's balance is (7000 + 7000 - 3000) = 11000. Bob's balance is 1000. Charlie's balance is (6000 + 6000 - 4000) = 8000.
Approach overview
Problem Overview: You are given two database tables: Users and Transactions. Each transaction changes an account’s balance by a positive or negative amount. The task is to compute the final balance for every user and return the users whose total balance exceeds 10000.
Approach 1: SQL Join and Group By Approach (O(n) time, O(1) extra space)
This approach uses standard relational database operations. Join the Users table with the Transactions table on the account field so every transaction is associated with the correct user. Then aggregate the transaction values using SUM(amount) while grouping by the account (or user name). After computing the balance for each account, filter results using a HAVING SUM(amount) > 10000 clause. The key insight is that SQL aggregation already performs the full scan and accumulation efficiently inside the database engine. This solution relies heavily on SQL aggregation and database join operations.
Approach 2: Programmatically Process Data (O(n) time, O(n) space)
If the same problem is handled in an application layer instead of SQL, you simulate the aggregation manually. Iterate through all transactions and accumulate balances in a hash map keyed by account. Each iteration updates the stored sum: balance[account] += amount. After processing all transactions, iterate through the Users list and check whether the stored balance exceeds 10000. If it does, return the user name and balance. This approach uses a hash map to maintain constant‑time updates and lookups while aggregating transaction values.
Recommended for interviews: The SQL JOIN + GROUP BY approach is the expected answer for database-focused problems. It demonstrates you understand relational aggregation and filtering with HAVING. Implementing the hash-map aggregation programmatically still shows strong fundamentals because it mirrors what the database engine does internally—iterate through records, accumulate totals, then filter the result.
Approach 1: SQL Join and Group By Approach
This approach involves using SQL to join the `Users` and `Transactions` tables. A GROUP BY clause will be used to calculate the sum of transactions for each account. We will then filter users whose balances exceed 10000. This is a straightforward SQL-based solution that effectively uses database functionalities.
SELECT U.name, SUM(T.amount) AS balance FROM Users U JOIN Transactions T ON U.account = T.account GROUP BY U.account, U.name HAVING SUM(T.amount) > 10000;The code joins the `Users` table and `Transactions` table using the common `account` column. It then groups the data by `account` and `name` and calculates the total balance using the SUM function on the `amount` column. A HAVING clause filters results to include only users with a balance greater than 10000.
Time Complexity: O(N), where N is the number of transactions. Space Complexity: O(M), where M is the number of users with a balance greater than 10000.
Approach 2: Programmatically Process Data
This approach involves programmatically processing the data from tables using a HashMap or Dictionary. First, we iterate over the transactions table to compute the balances. Then, we filter out users whose balances exceed the required threshold. This uses basic data structures and is implemented in multiple programming languages.
def high_balance_users(user_data, transaction_data):
balance_map = {}
for trans in transaction_data:
account = trans['account']
amount = trans['amount']
if account not in balance_map:
balance_map[account] = 0
balance_map[account] += amount
result = []
for user in user_data:
name = user['name']
account = user['account']
balance = balance_map.get(account, 0)
if balance > 10000:
result.append((name, balance))
return result
# Example usage
users = [{'account': 900001, 'name': 'Alice'}, {'account': 900002, 'name': 'Bob'}, {'account': 900003, 'name': 'Charlie'}]
transactions = [
{'trans_id': 1, 'account': 900001, 'amount': 7000, 'transacted_on': '2020-08-01'},
{'trans_id': 2, 'account': 900001, 'amount': 7000, 'transacted_on': '2020-09-01'},
{'trans_id': 3, 'account': 900001, 'amount': -3000, 'transacted_on': '2020-09-02'},
{'trans_id': 4, 'account': 900002, 'amount': 1000, 'transacted_on': '2020-09-12'},
{'trans_id': 5, 'account': 900003, 'amount': 6000, 'transacted_on': '2020-08-07'},
{'trans_id': 6, 'account': 900003, 'amount': 6000, 'transacted_on': '2020-09-07'},
{'trans_id': 7, 'account': 900003, 'amount': -4000, 'transacted_on': '2020-09-11'},
]
# Result: [('Alice', 11000)]
print(high_balance_users(users, transactions))import java.util.*;
public class BankAccountSummary {
public static List<String> highBalanceUsers(List<Map<String, Object>> users, List<Map<String, Object>> transactions) {
Map<Integer, Integer> balanceMap = new HashMap<>();
for (Map<String, Object> trans : transactions) {
Integer account = (Integer) trans.get("account");
Integer amount = (Integer) trans.get("amount");
balanceMap.put(account, balanceMap.getOrDefault(account, 0) + amount);
}
List<String> result = new ArrayList<>();
for (Map<String, Object> user : users) {
String name = (String) user.get("name");
Integer account = (Integer) user.get("account");
Integer balance = balanceMap.getOrDefault(account, 0);
if (balance > 10000) {
result.add(name);
}
}
return result;
}
public static void main(String[] args) {
List<Map<String, Object>> users = Arrays.asList(
new HashMap<String, Object>() {{ put("account", 900001); put("name", "Alice"); }},
new HashMap<String, Object>() {{ put("account", 900002); put("name", "Bob"); }},
new HashMap<String, Object>() {{ put("account", 900003); put("name", "Charlie"); }}
);
List<Map<String, Object>> transactions = Arrays.asList(
new HashMap<String, Object>() {{ put("trans_id", 1); put("account", 900001); put("amount", 7000); put("transacted_on", "2020-08-01"); }},
new HashMap<String, Object>() {{ put("trans_id", 2); put("account", 900001); put("amount", 7000); put("transacted_on", "2020-09-01"); }},
new HashMap<String, Object>() {{ put("trans_id", 3); put("account", 900001); put("amount", -3000); put("transacted_on", "2020-09-02"); }},
new HashMap<String, Object>() {{ put("trans_id", 4); put("account", 900002); put("amount", 1000); put("transacted_on", "2020-09-12"); }},
new HashMap<String, Object>() {{ put("trans_id", 5); put("account", 900003); put("amount", 6000); put("transacted_on", "2020-08-07"); }},
new HashMap<String, Object>() {{ put("trans_id", 6); put("account", 900003); put("amount", 6000); put("transacted_on", "2020-09-07"); }},
new HashMap<String, Object>() {{ put("trans_id", 7); put("account", 900003); put("amount", -4000); put("transacted_on", "2020-09-11"); }}
);
// Result should be ["Alice"]
System.out.println(highBalanceUsers(users, transactions));
}
}This Python function expects a list of users and a list of transactions. It creates a dictionary mapping accounts to their balances by iterating through the transactions. It then checks each user, computes their balance, and adds those users who have a balance greater than 10000 to the result list. This is returned and can be printed or processed further.
Time Complexity: O(N), where N is the number of transactions. Space Complexity: O(M), where M is the number of unique accounts.
Complexity comparison
| Approach | Complexity |
|---|---|
| SQL Join and Group By Approach | Time Complexity: O(N), where N is the number of transactions. Space Complexity: O(M), where M is the number of users with a balance greater than 10000. |
| Programmatically Process Data | Time Complexity: O(N), where N is the number of transactions. Space Complexity: O(M), where M is the number of unique accounts. |
Complexity analysis
| Approach | Time | Space | When to Use |
|---|---|---|---|
| SQL Join and Group By | O(n) | O(1) extra | Best for database queries where aggregation and filtering should happen inside the SQL engine |
| Programmatic Aggregation with Hash Map | O(n) | O(n) | Useful when processing transaction data in application code instead of a relational database |
Frequently asked questions
Is Bank Account Summary II easy or hard?
Bank Account Summary II is classified as an Easy database problem on LeetCode with an acceptance rate above 80%. The challenge mainly tests familiarity with SQL JOIN, GROUP BY aggregation, and filtering with HAVING.
Bank Account Summary II Python/Java solution
In Python or Java, iterate through all transactions and store balances in a dictionary or HashMap keyed by account. Update the balance with each transaction amount. After processing, check which users have totals greater than 10000 and return their names and balances.
How to solve Bank Account Summary II in O(n)?
Aggregate transaction amounts per account in a single pass. In SQL, join the tables and compute SUM(amount) grouped by account, then filter with HAVING SUM(amount) > 10000. In application code, iterate through transactions, store running totals in a hash map, and filter users whose balance exceeds the threshold.
What is the best approach for Bank Account Summary II?
The standard solution uses a SQL JOIN between the Users and Transactions tables followed by GROUP BY on the account and SUM(amount) to compute balances. A HAVING clause filters users with balances greater than 10000. This runs in O(n) time as the database scans and aggregates the transaction records once.
Is Bank Account Summary II asked at Google/Amazon/Meta?
This problem represents a common SQL interview pattern involving JOIN, GROUP BY, and HAVING filters. Similar aggregation problems frequently appear in database interview rounds at companies like Amazon, Meta, and other data-heavy engineering teams.
What data structure is used in Bank Account Summary II?
The SQL solution relies on relational aggregation using GROUP BY and SUM. When implemented programmatically, a hash map (dictionary) is typically used to accumulate balances for each account with constant-time updates.
What is the time complexity of Bank Account Summary II?
The optimal solution runs in O(n) time where n is the number of transactions. Each transaction contributes once to the SUM aggregation during the GROUP BY operation. Space complexity is O(1) extra when handled inside the database engine.
