Bank With the Largest Sum of Each User's Biggest Single Transfer

Read the full interview experience this question came from →

Quick Overview

A SQL question on linked bank accounts and fund transfers: find each user's largest single transfer at each bank, add those maxima up by bank name, and return the bank with the highest total. It tests two-level aggregation, joins, tie handling and choosing the right grain when one user holds several accounts at the same bank.

Bank With the Largest Sum of Each User's Biggest Single Transfer

Company: Robinhood

Role: Data Scientist

Category: Data Manipulation (SQL/Python)

Difficulty: hard

Interview Round: Technical Screen

Users of a trading app move money between the app and bank accounts they have linked to it. Two tables record the linked accounts and the transfers. For every user and every bank, find that user's largest single transfer at the bank. Then add those per-user maxima up by bank name, and return the bank with the largest total. One user can link several accounts, so one `user_id` can have several `bank_id` values, and two of a user's accounts can be at the same bank. The report singles this out as the detail that matters. It does not say whether "each bank" means each account or each bank name; this version fixes the rule in the Output Contract. ### Input Tables **`bank`**: one row per linked bank account. | Column | Type | Meaning | | --- | --- | --- | | `bank_id` | INTEGER | Primary key. Identifies one linked account, not a bank: several rows can share a `bank_name`. | | `user_id` | INTEGER | The user who linked the account. | | `bank_name` | TEXT | Name of the bank that holds the account. | **`fund_transfers`**: one row per transfer. | Column | Type | Meaning | | --- | --- | --- | | `transfer_id` | INTEGER | Primary key. | | `user_id` | INTEGER | The user who made the transfer. | | `bank_id` | INTEGER | The linked account used; references `bank.bank_id`. | | `amount` | NUMERIC(12, 2) | Transfer amount, always positive. | | `direction` | TEXT | `'out'` for money leaving the app to the bank account, `'in'` for money coming into the app from it. | ### Output Contract Write one read-only PostgreSQL query (a `SELECT`, optionally with `WITH` clauses) that returns exactly these columns: | Column | Meaning | | --- | --- | | `bank_name` | A bank with the largest total. | | `total_max_amount` | That bank's total, defined below. | - For each pair (`user_id`, `bank_name`) with at least one transfer, the user's maximum is the largest `amount` among that user's transfers through any of their accounts at that bank, in either direction. - A bank's `total_max_amount` is the sum of these maxima over all of its users. - Return every bank whose total equals the largest total, so a tie produces several rows. - Order the result by `bank_name`. ### Example `bank` | bank_id | user_id | bank_name | | --- | --- | --- | | 10 | 1 | Bank A | | 11 | 1 | Bank A | | 12 | 1 | Bank B | | 20 | 2 | Bank A | | 30 | 3 | Bank B | | 31 | 3 | Bank C | `fund_transfers` | transfer_id | user_id | bank_id | amount | direction | | --- | --- | --- | --- | --- | | 1 | 1 | 10 | 500.00 | in | | 2 | 1 | 11 | 700.00 | out | | 3 | 1 | 12 | 200.00 | in | | 4 | 2 | 20 | 300.00 | in | | 5 | 2 | 20 | 100.00 | out | | 6 | 3 | 30 | 900.00 | in | | 7 | 3 | 30 | 250.00 | out | Expected result: | bank_name | total_max_amount | | --- | --- | | Bank B | 1100.00 | User 1 has two accounts at Bank A, so their maximum there is 700.00, not 500.00 plus 700.00. Bank A's total is 700.00 + 300.00 = 1000.00, Bank B's is 200.00 + 900.00 = 1100.00, and Bank C has no transfers, so it has no total. ### Constraints and Clarifications - No column contains NULL. `direction` is always `'in'` or `'out'`, and both directions count. - Every `fund_transfers.bank_id` exists in `bank`, and `fund_transfers.user_id` always equals that account's `bank.user_id`. - Compare `bank_name` values exactly as stored; do not trim them or change their case. - When several of a user's transfers at one bank tie for the largest amount, that amount still counts once for the user. - A bank with no transfers does not appear. If `fund_transfers` is empty, return no rows. ```hint Fix the grain first Decide what one row represents after the first aggregation before writing the join, and check what a user with two accounts at the same bank contributes to that bank. ```

Overview: A SQL question on linked bank accounts and fund transfers: find each user's largest single transfer at each bank, add those maxima up by bank name, and return the bank with the highest total. It tests two-level aggregation, joins, tie handling and choosing the right grain when one user holds several accounts at the same bank.

Read the full Robinhood Data Scientist interview experience this question came from

Robinhood logo
Robinhood
Oct 28, 2026
hardData ScientistTechnical ScreenData Manipulation (SQL/Python)
0
0

Users of a trading app move money between the app and bank accounts they have linked to it. Two tables record the linked accounts and the transfers. For every user and every bank, find that user's largest single transfer at the bank. Then add those per-user maxima up by bank name, and return the bank with the largest total.

One user can link several accounts, so one user_id can have several bank_id values, and two of a user's accounts can be at the same bank. The report singles this out as the detail that matters. It does not say whether "each bank" means each account or each bank name; this version fixes the rule in the Output Contract.

Input Tables

bank: one row per linked bank account.

ColumnTypeMeaning
bank_idINTEGERPrimary key. Identifies one linked account, not a bank: several rows can share a bank_name.
user_idINTEGERThe user who linked the account.
bank_nameTEXTName of the bank that holds the account.

fund_transfers: one row per transfer.

ColumnTypeMeaning
transfer_idINTEGERPrimary key.
user_idINTEGERThe user who made the transfer.
bank_idINTEGERThe linked account used; references bank.bank_id.
amountNUMERIC(12, 2)Transfer amount, always positive.
directionTEXT'out' for money leaving the app to the bank account, 'in' for money coming into the app from it.

Output Contract

Write one read-only PostgreSQL query (a SELECT, optionally with WITH clauses) that returns exactly these columns:

ColumnMeaning
bank_nameA bank with the largest total.
total_max_amountThat bank's total, defined below.
  • For each pair ( user_id , bank_name ) with at least one transfer, the user's maximum is the largest amount among that user's transfers through any of their accounts at that bank, in either direction.
  • A bank's total_max_amount is the sum of these maxima over all of its users.
  • Return every bank whose total equals the largest total, so a tie produces several rows.
  • Order the result by bank_name .

Example

bank

bank_iduser_idbank_name
101Bank A
111Bank A
121Bank B
202Bank A
303Bank B
313Bank C

fund_transfers

transfer_iduser_idbank_idamountdirection
1110500.00in
2111700.00out
3112200.00in
4220300.00in
5220100.00out
6330900.00in
7330250.00out

Expected result:

bank_nametotal_max_amount
Bank B1100.00

User 1 has two accounts at Bank A, so their maximum there is 700.00, not 500.00 plus 700.00. Bank A's total is 700.00 + 300.00 = 1000.00, Bank B's is 200.00 + 900.00 = 1100.00, and Bank C has no transfers, so it has no total.

Constraints and Clarifications

  • No column contains NULL. direction is always 'in' or 'out' , and both directions count.
  • Every fund_transfers.bank_id exists in bank , and fund_transfers.user_id always equals that account's bank.user_id .
  • Compare bank_name values exactly as stored; do not trim them or change their case.
  • When several of a user's transfers at one bank tie for the largest amount, that amount still counts once for the user.
  • A bank with no transfers does not appear. If fund_transfers is empty, return no rows.