Quick Overview

Compare bank-account balances for a target calendar month, report match status, and distinguish missing comparison records from zero balances.

Reconcile Monthly Bank-Account Balances Across Two Datasets

Company: Stripe

Role: Software Engineer

Category: Data Manipulation (SQL/Python)

Difficulty: medium

Interview Round: Technical Screen

Write a PostgreSQL query that compares monthly bank-account balances from two imported datasets and marks each account in the first dataset as matching or not matching the second. ### Tables Both `primary_balances` and `comparison_balances` have columns: `bank_name text, account_name text, start_date date, end_date date, balance numeric(18,2)` `report_month(month_start date)` contains exactly one row whose value is the first day of the target month. ### Exercise Conventions - A record belongs to the calendar month containing its `end_date`. - In each input table, there is at most one record per bank/account/end-date month. All fields are non-null, and `start_date <= end_date`. - Report each primary record in the target month. Accounts appearing only in the comparison table are outside this report. - Match records by bank name, account name, and target month, even if the two end dates within that month differ. - A primary record is `Match` only when a comparison record exists and the two numeric balances are equal. Otherwise it is `Not Match`. - Do not sum records across years or treat a missing comparison record as a zero balance. These schema and missing-record conventions make the monthly reconciliation task precise. ### Output Return `bank_name`, `account_name`, `end_date`, `balance`, and `match_status`. The end date and balance come from the primary record. Sort by bank name and then account name using `COLLATE "C"` for deterministic text order. ### Example Target month: `2021-12-01`. `primary_balances`: | bank_name | account_name | start_date | end_date | balance | |---|---|---|---|---:| | Bay | 02 | 2021-12-01 | 2021-12-31 | 300.00 | | Harbor | 01 | 2021-12-01 | 2021-12-31 | 150.00 | | Harbor | 01 | 2020-12-01 | 2020-12-31 | 999.00 | `comparison_balances`: | bank_name | account_name | start_date | end_date | balance | |---|---|---|---|---:| | Bay | 02 | 2021-12-01 | 2021-12-31 | 250.00 | | Harbor | 01 | 2021-12-01 | 2021-12-30 | 150.00 | Expected output: | bank_name | account_name | end_date | balance | match_status | |---|---|---|---:|---| | Bay | 02 | 2021-12-31 | 300.00 | Not Match | | Harbor | 01 | 2021-12-31 | 150.00 | Match |

Overview: Compare bank-account balances for a target calendar month, report match status, and distinguish missing comparison records from zero balances.

Read the full Stripe Software Engineer interview experience this question came from

Write a PostgreSQL query that compares monthly bank-account balances from two imported datasets and marks each account in the first dataset as matching or not matching the second. Tables: - primary_balances(bank_name text, account_name text, start_date date, end_date date, balance numeric(18,2)) is the first imported dataset. - comparison_balances(bank_name text, account_name text, start_date date, end_date date, balance numeric(18,2)) is the second imported dataset, with the same columns. - report_month(month_start date) contains exactly one row whose value is the first day of the target month. Conventions: - A record belongs to the calendar month containing its end_date. - In each input table, there is at most one record per bank_name/account_name/end-date month. All fields are non-null, and start_date <= end_date. - Report each primary_balances record in the target month. Accounts appearing only in comparison_balances are outside this report. - Match records by bank_name, account_name, and target month, even if the two end dates within that month differ. - A primary record is 'Match' only when a comparison record exists and the two numeric balances are equal. Otherwise it is 'Not Match'. - Do not sum records across years or treat a missing comparison record as a zero balance. Output: return bank_name, account_name, end_date, balance, and match_status. The end_date and balance come from the primary record. Sort by bank_name and then account_name using COLLATE "C" for deterministic text order.

Tables

primary_balances(bank_name TEXT, account_name TEXT, start_date DATE, end_date DATE, balance NUMERIC(18,2))

comparison_balances(bank_name TEXT, account_name TEXT, start_date DATE, end_date DATE, balance NUMERIC(18,2))

report_month(month_start DATE)

Hints

  1. Use the single report_month row to decide which calendar month each end_date must fall in.
  2. Every target-month primary record must appear in the output, whether or not a comparison record exists for it.

Loading coding console...