cswork / libraryOpen practice workspace

Coding questions · Bilt Rewards

Write SQL to Join Merchants and Triple Restaurant Points

This question evaluates SQL querying and data engineering competencies—specifically JOINs, conditional logic (CASE), ETL staging, data cleaning, indexing, and approximate string matching—within the data manipulation and database domain and emphasizes practical application of SQL for transforming transactional datasets.

You are given: (1) a CSV file merchants.csv with columns: merchant_name, merchant_code, category; (2) a database table transactions(user_id INT, merchant_name TEXT, amount DECIMAL(10, 2), transacted_at TIMESTAMP). Tasks:

  1. Load the CSV into a staging table merchants(merchant_name TEXT, merchant_code TEXT, category TEXT).
  2. Write a single SQL query that returns, for each transaction, user_id, merchant_code, category, base_points = FLOOR(amount), and final_points where Restaurant transactions earn 3x base_points and all others 1x. If merchant_name does not match any row in merchants, set merchant_code = 'UNKNOWN' and category = 'UNKNOWN'.
  3. Explain why pushing this transformation into SQL (using JOIN and CASE) may be preferable to post-processing in application code.
  4. Describe indexes and data-cleaning steps you would apply, and how you would handle approximate name matching if merchant_name strings are inconsistent.

Join Merchants and Transactions to Compute Restaurant Reward Points

You have two tables:

  1. merchants(merchant_name, merchant_code, category) – already loaded from a CSV.
  2. transactions(user_id, merchant_name, amount, transacted_at).

Write a single SQL query that returns, for each row in transactions:

  • user_id,
  • merchant_code,
  • category,
  • base_points = FLOOR(amount),
  • final_points, where transactions with category = 'Restaurant' earn 3x base_points and all other categories earn 1x base_points.

If a transaction.merchant_name does not match any row in merchants, set merchant_code = 'UNKNOWN' and category = 'UNKNOWN' for that transaction, and treat it as a non-Restaurant transaction.

Table merchants

columntypeconstraints
merchant_nameVARCHAR(100)NOT NULL
merchant_codeVARCHAR(20)PRIMARY KEY, NOT NULL
categoryVARCHAR(50)NOT NULL

Sample data:

categorymerchant_codemerchant_name
RestaurantSTB001Starbucks
TransportUBR001Uber
GroceryWFD001Whole Foods
RestaurantDIN001Local Diner

Table transactions

columntypeconstraints
user_idINTNOT NULL
merchant_nameVARCHAR(100)NOT NULL
amountDECIMAL(10,2)NOT NULL
transacted_atTIMESTAMPNOT NULL

Sample data:

amountmerchant_nametransacted_atuser_id
5.75Starbucks2025-05-20 08:15:001
12.4Uber2025-05-21 09:30:001
30.1Whole Foods2025-05-22 13:00:002
20Unknown Shop2025-05-23 18:45:003
15.5Local Diner2025-05-24 19:20:002

Expected output

One row per transaction, with merchant details (or 'UNKNOWN' when there is no match), the base_points as FLOOR(amount), and final_points where Restaurant category earns 3x base_points and others earn 1x.

base_pointscategoryfinal_pointsmerchant_codeuser_id
5Restaurant15STB0011
12Transport12UBR0011
30Grocery30WFD0012
20UNKNOWN20UNKNOWN3
15Restaurant45DIN0012

Hints

  1. Use a LEFT JOIN from transactions to merchants so that transactions without a matching merchant still appear.
  2. Use COALESCE to default merchant_code and category to 'UNKNOWN', and a CASE expression to apply 3x points only when the category is 'Restaurant'.