Banking Dataset for SQL Practice
This ready-made banking dataset is designed for analysts practicing SQL. It contains 41,366 rows across 3 tables, covering customer information, account details, and financial transactions. Analyze account balances, transaction patterns, and customer behavior within the date range of 2022-01-01 to 2023-12-31.
At a glance
- 3tables
- 41,366rows
- 14columns
- Jan 2022 – Dec 2023date range
The 3 tables
preview and data dictionary per tableCustomers customers · dimension table · 1,000 rows
Contains information about 1,000 banking customers.
Preview
| customer_iduuid | first_namestring | last_namestring | citystring | countrystring |
|---|---|---|---|---|
| 7e3675aa-1a40-4d95-8168-e8349e87334b | Penelope | Thompson | Philadelphia | USA |
| 3f40ade4-21df-470b-a0c2-28aadfd30b25 | Sophia | Johnson | Columbus | USA |
| 5f765331-a9b8-46bf-961c-1b6b38b0e09c | Emma | Patterson | Indianapolis | USA |
| 0a037b2b-79d2-4a2b-94c2-00e7286dbfae | Ava | Taylor | Detroit | USA |
| 9594668e-7ba4-441f-b5bb-9b069c1e7326 | Isabella | Jackson | Baltimore | USA |
| fe6c0677-8787-44ee-b0f9-17186b56f8b6 | Mia | Peterson | Louisville | USA |
| 3bbe022f-9d5b-40ef-8d3a-2d94ec522127 | Charlotte | Thomas | Philadelphia | USA |
| d8e13ccd-e538-4c97-81c6-c10d95abf9c8 | Amelia | Jenkins | Columbus | USA |
| fd9abd04-426f-49a2-be78-122d3ca93c0c | Harper | Parker | Indianapolis | USA |
| e28b2c96-e8fa-4c97-bb70-d468e70eda58 | Evelyn | Turner | Detroit | USA |
Data dictionary
| column | type | description | example | null % |
|---|---|---|---|---|
customer_ | uuid | Unique identifier for each banking customer.unique | 7e3675aa-1a40-4d95-8168-e8349e87334b | 0% |
first_ | string | Customer's given first name. | Penelope | 0% |
last_ | string | Customer's surname or family name. | Thompson | 0% |
city | string | Customer's residential city in the United States. | Philadelphia | 0% |
country | string | Customer's country of residence, fixed to USA. | USA | 0% |
Accounts accounts · table · 3,000 rows
Details of 3,000 bank accounts, linked to customers.
Preview
| account_iduuid | account_typestring | balancedecimal | customer_iduuid |
|---|---|---|---|
| 6c48e9de-46ab-4c4c-b1f9-e52c283ace6d | Checking | 2570.53 | 7a9c445f-9d10-43b1-a266-f6eebc75615d |
| f2aec520-7f3c-4f86-ae2b-de844d4fea12 | Checking | 1823 | 30637d21-cbac-4f09-9d24-a4a14baa1c10 |
| f46b26be-7511-4d96-8904-4b8daa6a48d6 | Checking | 7583.46 | 8010684d-2ffa-41c9-a4a8-562d1e7323e0 |
| f0d5a2c2-1830-4663-a184-b70e9464d90f | Checking | 17313.72 | fc6828e0-4d14-4f0d-9401-6da0a5fe3aa7 |
| 95097ccb-1249-4188-9f84-28f2e56b8627 | Checking | 3714.24 | e9ee3828-3ffc-491f-ba34-c09be0130e82 |
| 8212c8f8-aac4-4435-ab7b-0933359264fd | Checking | 1820.28 | 3ab94367-8b4d-4bae-8c05-af28c79347f1 |
| c5035f6e-1295-4ab6-a2c9-bb724c96dd50 | Checking | 8513.71 | 25e783ec-dc3f-4684-8102-40bce850ce4b |
| 1a82f404-f1da-42ce-823f-7159f63f7b94 | Checking | 527.9 | dbd06d4d-2759-47b4-94be-dce843c551f2 |
| e05105e6-9536-4ef2-ac81-5d6149fc67eb | Checking | 18884.23 | 9cc669f7-6d89-4dd2-a194-3bc89511d7c8 |
| 8e57ac62-45b6-4794-b5f9-ce1c96c74b2e | Checking | 9285.87 | 7f56f9b2-7146-44cc-ab73-3de1113378c5 |
Data dictionary
| column | type | description | example | null % |
|---|---|---|---|---|
account_ | uuid | Unique primary identifier for the bank account.unique | 6c48e9de-46ab-4c4c-b1f9-e52c283ace6d | 0% |
account_ | string | Category of bank account held by the customer. | Checking | 0% |
balance | decimal | Current balance of the account in USD, allowing negative values. | 2570.53 | 0% |
customer_ | uuid | Foreign key linking to the customers table. | 7a9c445f-9d10-43b1-a266-f6eebc75615d | 0% |
Transactions transactions · fact table · 37,366 rows
Records of 37,366 financial transactions.
Preview
| transaction_iduuid | transaction_datedate | typestring | amountdecimal | account_iduuid |
|---|---|---|---|---|
| 02fd1770-d480-4522-b50e-556d53bf79b2 | 2023-05-09 | Deposit | 83.07 | c5035f6e-1295-4ab6-a2c9-bb724c96dd50 |
Data dictionary
| column | type | description | example | null % |
|---|---|---|---|---|
transaction_ | uuid | Unique identifier for the financial transaction. | 9fdd2f49-b9e0-4236-ba77-2ec838276b6b | 0% |
transaction_ | date | The date on which the transaction was posted. | 2023-10-26 | 0% |
type | string | The classification of the financial transaction. | Deposit | 0% |
amount | decimal | The monetary value of the transaction in USD. | 114.32 | 0% |
account_ | uuid | Foreign key linking to the accounts table. | 2c16adfc-0c03-4a50-8430-d4cee785f2b9 | 0% |
How the tables join
accounts.customer_id references customers.customer_idmany to one: each Accounts row points to one Customers rowtransactions.account_id references accounts.account_idmany to one: each Transactions row points to one Accounts row
Questions to answer with it
Write a SQL query to find the total balance for each customer, joining the accounts and customers tables.
Use a SUM aggregate function on the balance column and group by customer.
tables: accounts, customers
Write a SQL query to list all transactions for a specific account (e.g., account_id = '6c48e9de-46ab-4c4c-b1f9-e52c283ace6d') within a date range (e.g., '2023-01-01' to '2023-12-31').
Use a WHERE clause with conditions for account_id and transaction_date.
tables: transactions
Write a SQL query to identify customers who have more than one account type, using a GROUP BY and HAVING clause.
Group by customer_id and count distinct account_types, then filter with HAVING.
tables: accounts, customers
Calculate the average transaction amount for each transaction type (Deposit, Withdrawal, etc.) using SQL.
Use the AVG aggregate function and group by the transaction type.
tables: transactions
Starter SQL
run against this data before publishingTable names match the SQLite file and the SQL script.
Total Balance Per Customer
SELECT c.customer_id, c.first_name, c.last_name, SUM(a.balance) AS total_balance
FROM customers c
JOIN accounts a ON c.customer_id = a.customer_id
GROUP BY c.customer_id, c.first_name, c.last_name
ORDER BY total_balance DESC
LIMIT 20;Transactions for a Specific Account
SELECT transaction_id, transaction_date, type, amount
FROM transactions
WHERE account_id = '6c48e9de-46ab-4c4c-b1f9-e52c283ace6d'
AND transaction_date BETWEEN '2023-01-01' AND '2023-12-31'
ORDER BY transaction_date
LIMIT 20;Customers with Multiple Account Types
SELECT c.customer_id, c.first_name, c.last_name, COUNT(DISTINCT a.account_type) AS num_account_types
FROM customers c
JOIN accounts a ON c.customer_id = a.customer_id
GROUP BY c.customer_id, c.first_name, c.last_name
HAVING COUNT(DISTINCT a.account_type) > 1
LIMIT 20;Average Transaction Amount by Type
SELECT type, AVG(amount) AS average_amount
FROM transactions
GROUP BY type
LIMIT 20;Recent Transactions with Account Type (Window Function)
SELECT
t.transaction_id,
t.transaction_date,
t.amount,
a.account_type,
ROW_NUMBER() OVER (PARTITION BY t.account_id ORDER BY t.transaction_date DESC) as rn
FROM transactions t
JOIN accounts a ON t.account_id = a.account_id
WHERE t.transaction_date BETWEEN '2023-01-01' AND '2023-12-31'
LIMIT 20;Load it with pandas
import pandas as pd
# Unzip the CSV download first: one file per table
customers = pd.read_csv("customers.csv")
accounts = pd.read_csv("accounts.csv")
transactions = pd.read_csv("transactions.csv")
# Join accounts to customers
df = accounts.merge(customers, left_on="customer_id", right_on="customer_id", how="left", suffixes=("", "_customers"))
print(df.groupby("city").size().sort_values(ascending=False))Using it in your tool
- SQL
- The SQLite database contains 3 tables: customers, accounts, and transactions. Primary keys are customer_id (customers), account_id (accounts), and transaction_id (transactions). Foreign key relationships are accounts.customer_id -> customers.customer_id and transactions.account_id -> accounts.account_id.
Formats available
- CSV (zip)One CSV file per table, zipped
- Excel workbookOne worksheet per table
- SQLite databaseA ready-to-query database file with every table
- Parquet (zip)One Parquet file per table, zipped
- SQL scriptCREATE TABLE with primary and foreign keys, then INSERTs
- CSVA single CSV file
- JSONA single JSON file
How this data was generated
Synthetic data. Every row was generated: no real people, customers or companies are in this dataset.
Synthetic data generated by GoMask DataFactory from a relational blueprint: keys, links and rules are enforced in code, text columns are filled by a language model. No real people, companies or transactions.
- Data was generated using GoMask DataFactory.
- Customer data is based on US cities.
- Transaction amounts and balances are within realistic ranges.
- Checked by an automated quality gate: unique keys, no orphan foreign keys, required columns filled, declared rules and date ranges (realism score 92).
Limitations
- The dataset is synthetic and does not represent real-world individuals or events.
- Geographic data is limited to US cities.
- Does not include details on loan interest rates or credit card specific features.
- Distributions and correlations are modelled, not measured from real records.
blueprint · banking-dataset-for-sql
Scale this dataset
Same tables. As many rows as you need.
Open the blueprint behind these 3 tables in Data Factory: keep the relationships, change a column, and generate it at the size you need.
- 200,000 rows
- 1,000,000 rows
- Tables
- customers, accounts, transactions
- Licence
- yours to use, including commercially
- API slug
- banking-dataset-for-sql