Purchase Log

A medium SQL interview practice problem on DataDriven. Write the query and run it against a real database, with instant feedback.

Domain
SQL
Difficulty
medium
Seniority
L3
Asked in
Tata Consultancy Services

Problem

A purchase only makes our audit log if it came in above fifty dollars, and every such purchase gets its own line. For each of those rows in transactions, show the buyer's username from users next to the amount spent and the purchase date.

Names on receipts, not just IDs.

Tables

users

Columns: user_id INTEGER, username TEXT, email TEXT, signup_date TEXT, account_status TEXT, age_bucket TEXT

users: 10 of 200 rows
user_idusernameemailsignup_dateaccount_statusage_bucket
100alicealice@example.com2025-02-02inactive25-34
197aaron42aaron42@example.com2026-03-03suspended35-44
294 ameliaamelia@example.com2024-04-04pending_verification45-54
391arjun arjun@example.com2025-05-05active55-64
488ava99ava99@example.com2026-06-06inactive65+
585andrew_kandrew_k@example.com2024-07-07suspendedNULL
682anikaanika@example.com2025-08-08 16:34:00pending_verification18-24
779aidenaiden@example.com2026-09-09 14:53:00active25-34
876aria_baria_b@example.com2024-10-10inactive35-44
973brianbrian@example.com2025-11-11suspended45-54

transactions

Columns: transaction_id INTEGER, user_id INTEGER, product_id INTEGER, quantity INTEGER, total_amount REAL, transaction_date TEXT

transactions: 10 of 200 rows
transaction_iduser_idproduct_idquantitytotal_amounttransaction_date
10671971001223.462026-02-02
11342941050336.932026-03-03
12013911099450.42026-04-04
12684881148563.872026-05-05
13355851197002026-06-06
14026821246290.812026-07-07
146977912953104.282026-08-08
153687613444117.752026-09-09
160397313935-452026-01-10
1670107014421144.692026-02-11

Expected output

First 5 of 194 rows
usernametotal_amounttransaction_date
arjun 50.42026-04-04
ava9963.872026-05-05
anika90.812026-07-07
aiden104.282026-08-08
aria_b117.752026-09-09

Worked solution and explanation

What this really is

This is a lookup join dressed up as an audit log. Everything the log needs already sits in transactions except the one column that makes it readable: the buyer's name lives only in users. Anyone can write WHERE total_amount > 50. What separates candidates is noticing that user_id is not a username and reaching across to users for it. Skip the join and you hand the auditors a column of opaque ids. Read the bar as >= 50 and a purchase of exactly fifty dollars leaks into a report meant to hold only purchases above it.

Building it

Step 1: Fix the grain: one row per purchase

The log lists purchases, so every row of transactions that clears the bar is a row of output. A buyer with a dozen qualifying purchases appears a dozen times. There is nothing to collapse, so no GROUP BY and no DISTINCT.

Step 2: Fetch the name from users

Inner-join users to transactions on user_id. Each transaction has exactly one buyer and user_id is unique in users, so the join attaches a name to each purchase without multiplying rows. Every buyer on this data has a users row, so no purchase falls out either.

Step 3: Apply the threshold strictly

total_amount > 50 keeps the 50.40 purchase and would turn away one at exactly 50.00. The same predicate also clears out the voided 0.00 sale and the -45.00 refund, which sit below the bar under any reading.

Join `users` to `transactions` for the purchase log
SELECT u.username, t.total_amount, t.transaction_date
FROM users u
JOIN transactions t ON u.user_id = t.user_id
WHERE t.total_amount > 50
Single-table shortcut
SELECT user_id, total_amount, transaction_date FROM transactions WHERE total_amount > 50 runs and even returns the right number of rows, but the first column holds numbers like 391 that nobody reading the audit can interpret.
With the lookup
The join swaps that number for username, so the same row reads 'arjun ' with its amount and date: the thing the log was asked for in the first place.

Common follow-up questions