Watch 10 video solutions for Market Analysis I, a medium level problem involving Database. This walkthrough by Everyday Data Science has 4,447 views views. Want to try solving it yourself? Practice on FleetCode or read the detailed text solution.
Table: Users
+----------------+---------+ | Column Name | Type | +----------------+---------+ | user_id | int | | join_date | date | | favorite_brand | varchar | +----------------+---------+ user_id is the primary key (column with unique values) of this table. This table has the info of the users of an online shopping website where users can sell and buy items.
Table: Orders
+---------------+---------+ | Column Name | Type | +---------------+---------+ | order_id | int | | order_date | date | | item_id | int | | buyer_id | int | | seller_id | int | +---------------+---------+ order_id is the primary key (column with unique values) of this table. item_id is a foreign key (reference column) to the Items table. buyer_id and seller_id are foreign keys to the Users table.
Table: Items
+---------------+---------+ | Column Name | Type | +---------------+---------+ | item_id | int | | item_brand | varchar | +---------------+---------+ item_id is the primary key (column with unique values) of this table.
Write a solution to find for each user, the join date and the number of orders they made as a buyer in 2019.
Return the result table in any order.
The result format is in the following example.
Example 1:
Input: Users table: +---------+------------+----------------+ | user_id | join_date | favorite_brand | +---------+------------+----------------+ | 1 | 2018-01-01 | Lenovo | | 2 | 2018-02-09 | Samsung | | 3 | 2018-01-19 | LG | | 4 | 2018-05-21 | HP | +---------+------------+----------------+ Orders table: +----------+------------+---------+----------+-----------+ | order_id | order_date | item_id | buyer_id | seller_id | +----------+------------+---------+----------+-----------+ | 1 | 2019-08-01 | 4 | 1 | 2 | | 2 | 2018-08-02 | 2 | 1 | 3 | | 3 | 2019-08-03 | 3 | 2 | 3 | | 4 | 2018-08-04 | 1 | 4 | 2 | | 5 | 2018-08-04 | 1 | 3 | 4 | | 6 | 2019-08-05 | 2 | 2 | 4 | +----------+------------+---------+----------+-----------+ Items table: +---------+------------+ | item_id | item_brand | +---------+------------+ | 1 | Samsung | | 2 | Lenovo | | 3 | LG | | 4 | HP | +---------+------------+ Output: +-----------+------------+----------------+ | buyer_id | join_date | orders_in_2019 | +-----------+------------+----------------+ | 1 | 2018-01-01 | 1 | | 2 | 2018-02-09 | 2 | | 3 | 2018-01-19 | 0 | | 4 | 2018-05-21 | 0 | +-----------+------------+----------------+
Problem Overview: You are given three tables: Users, Orders, and Items. For every user, return their user_id, join_date, and the number of orders they placed in the year 2019. Users with no orders in 2019 must still appear in the result with a count of 0. The core challenge is correctly joining user records with filtered order data while preserving users who have no matching rows.
Approach 1: SQL Join with Subquery (O(U + O) time, O(1) extra space)
This approach filters orders from 2019 first, then aggregates them per buyer before joining with the Users table. A subquery scans the Orders table, applies a YEAR(order_date) = 2019 condition, and groups results by buyer_id using COUNT(*). The outer query performs a LEFT JOIN between Users and the aggregated result so that users without orders still appear. Missing counts are replaced with 0 using COALESCE. This pattern keeps aggregation isolated and simplifies the final join, which is common in SQL interview problems involving reporting queries.
Approach 2: Iterative Filtering and Counting (O(U + O) time, O(U) space)
In languages like Java or C++, you can simulate the database logic using collections. First iterate through the orders list and filter entries where order_date belongs to 2019. Maintain a hash map that maps buyer_id → order_count, incrementing the value each time a qualifying order appears. Next iterate through the users list and construct the result by reading counts from the map, defaulting to 0 if the user never appears. This mirrors a manual hash map aggregation followed by a lookup join. The method is useful when solving database-style questions in general programming interviews or when implementing analytics logic outside a database.
Both strategies rely on the same insight: filter orders to the relevant year first, then aggregate by buyer. The SQL solution relies on relational operations like LEFT JOIN and GROUP BY, while the iterative solution uses hash-based counting and lookup logic often seen in database-style problems implemented in application code.
Recommended for interviews: The SQL aggregation with LEFT JOIN is the expected answer for database-focused interviews. It shows that you understand join semantics, grouping, and how to preserve unmatched rows. Implementing the iterative counting approach demonstrates deeper understanding of how database joins and aggregations work under the hood.
| Approach | Time | Space | When to Use |
|---|---|---|---|
| SQL Join with Subquery | O(U + O) | O(1) | Best for SQL interviews and relational database queries where aggregation and joins are required |
| Iterative Filtering and Counting | O(U + O) | O(U) | Useful when implementing database-style aggregation in application code using maps |