cswork / libraryOpen practice workspace

Coding questions · TikTok

Debug a Hive query

This question evaluates a candidate's ability to debug and validate Hive SQL queries, assessing competencies in identifying logical errors (incorrect join conditions, aggregation and window function misuse, filters and partition predicates), validating results with test cases, and reasoning about performance optimizations.

You are given a prewritten Hive SQL query that produces incorrect results. Describe how you would debug it: identify logical errors (e.g., join conditions, aggregations, window functions, filters, partition predicates), fix the query, and validate correctness with test cases and data checks. Explain any performance optimizations you would make and why.

Fix and Optimize a Monthly GMV Aggregation in Hive

You are computing monthly revenue metrics for an e-commerce platform. Using the users, orders, and payments tables described below, write a single PostgreSQL query that produces one row per (calendar month, country) combination, restricted to the first quarter of 2025.

Qualifying-order rules (an order must satisfy ALL of these to be counted):

  • The order's status is 'completed'.
  • The order's order_date falls between 2025-01-01 and 2025-03-31 (inclusive).
  • There exists at least one row in payments for that order whose payment_date is between the order's order_date and 7 days after order_date (inclusive). An order is counted once no matter how many payments it has.

Output: For each (month, country) that has at least one qualifying order, return exactly these columns:

  • order_month — the order's month in YYYY-MM format (derived from order_date).
  • country — the country of the order's user (from users.country).
  • total_gmv — the sum of orders.total_amount over the qualifying orders in that (month, country).
  • paying_users — the number of distinct users who placed at least one qualifying order in that (month, country).
  • avg_order_value — total_gmv divided by the number of qualifying orders in that (month, country), rounded to 2 decimal places.
  • top_customer_id — the user_id whose summed total_amount of qualifying orders is the highest within that (month, country). Break ties by choosing the smallest user_id.

Sort the result by order_month ascending, then country ascending.

Table users

columntypeconstraints
user_idINTPRIMARY KEY, NOT NULL
countryVARCHAR(2)NOT NULL
signup_dateDATE

Sample data:

countrysignup_dateuser_id
US2024-12-151
US2024-12-202
CA2025-01-053
US2025-02-014

Table orders

columntypeconstraints
order_idINTPRIMARY KEY, NOT NULL
user_idINTNOT NULL
order_dateDATENOT NULL
statusVARCHAR(20)NOT NULL
total_amountDECIMAL(10,2)NOT NULL

Sample data:

order_dateorder_idstatustotal_amountuser_id
2025-01-05101completed1001
2025-01-20102cancelled501
2025-01-15103completed802
2025-02-10104completed1202
2025-02-12105completed2003
2025-03-01106completed1504
2024-12-28107completed601
2025-03-20108pending903
2025-03-25109completed502

Table payments

columntypeconstraints
payment_idINTPRIMARY KEY, NOT NULL
order_idINTNOT NULL
payment_dateDATENOT NULL
amountDECIMAL(10,2)NOT NULL
payment_methodVARCHAR(20)NOT NULL

Sample data:

amountorder_idpayment_datepayment_idpayment_method
1001012025-01-061001card
501022025-01-211002card
801032025-01-161003paypal
1201042025-02-151004card
2001052025-02-201005card
1501062025-03-051006card
601072024-12-291007card
501092025-04-151008card

Expected output

One row per (order_month, country) for qualifying completed orders in Q1 2025; only US qualifies in the sample data, yielding three rows (Jan/Feb/Mar) with GMV, distinct paying users, rounded avg order value, and the top customer by GMV.

avg_order_valuecountryorder_monthpaying_userstop_customer_idtotal_gmv
90.00US2025-0121180.00
120.00US2025-0212120.00
150.00US2025-0314150.00

Hints

  1. Filter to completed Q1-2025 orders first, and use an EXISTS subquery against payments (rather than a direct join) so an order with several qualifying payments is still counted only once.
  2. In Postgres, add days to a DATE with order_date + 7, and format the month with TO_CHAR(order_date, 'YYYY-MM').
  3. Compute per-user monthly GMV in one CTE, then use ROW_NUMBER() OVER (PARTITION BY order_month, country ORDER BY user_gmv DESC, user_id ASC) and keep row 1 to get top_customer_id.