Sales Analysis III - Solution & Explanation
Problem Statement
Table: Product
+--------------+---------+ | Column Name | Type | +--------------+---------+ | product_id | int | | product_name | varchar | | unit_price | int | +--------------+---------+ product_id is the primary key (column with unique values) of this table. Each row of this table indicates the name and the price of each product.
Table: Sales
+-------------+---------+ | Column Name | Type | +-------------+---------+ | seller_id | int | | product_id | int | | buyer_id | int | | sale_date | date | | quantity | int | | price | int | +-------------+---------+ This table can have duplicate rows. product_id is a foreign key (reference column) to the Product table. Each row of this table contains some information about one sale.
Write a solution to report the products that were only sold in the first quarter of 2019. That is, between 2019-01-01 and 2019-03-31 inclusive.
Return the result table in any order.
The result format is in the following example.
Example 1:
Input: Product table: +------------+--------------+------------+ | product_id | product_name | unit_price | +------------+--------------+------------+ | 1 | S8 | 1000 | | 2 | G4 | 800 | | 3 | iPhone | 1400 | +------------+--------------+------------+ Sales table: +-----------+------------+----------+------------+----------+-------+ | seller_id | product_id | buyer_id | sale_date | quantity | price | +-----------+------------+----------+------------+----------+-------+ | 1 | 1 | 1 | 2019-01-21 | 2 | 2000 | | 1 | 2 | 2 | 2019-02-17 | 1 | 800 | | 2 | 2 | 3 | 2019-06-02 | 1 | 800 | | 3 | 3 | 4 | 2019-05-13 | 2 | 2800 | +-----------+------------+----------+------------+----------+-------+ Output: +-------------+--------------+ | product_id | product_name | +-------------+--------------+ | 1 | S8 | +-------------+--------------+ Explanation: The product with id 1 was only sold in the spring of 2019. The product with id 2 was sold in the spring of 2019 but was also sold after the spring of 2019. The product with id 3 was sold after spring 2019. We return only product 1 as it is the product that was only sold in the spring of 2019.
Approach Overview
Problem Overview: You need to return products that were sold only during the first quarter of 2019 (Jan 1 to Mar 31). If a product has even one sale outside this range, it must be excluded. The result includes product_id and product_name.
Approach 1: SQL JOIN + GROUP BY with Conditional Filtering (O(n) time, O(n) space)
This approach joins the Sales table with the Product table using product_id. After joining, group rows by product and analyze the sale dates for each group. The key idea is to check that the minimum sale date is on or after 2019-01-01 and the maximum sale date is on or before 2019-03-31. If both conditions hold, every sale for that product occurred inside Q1 2019.
Aggregation functions like MIN(sale_date) and MAX(sale_date) make this efficient because you avoid scanning the same product multiple times. The database engine performs a single grouped pass over the rows. This pattern is common in SQL problems that require validating constraints across grouped records.
Approach 2: SQL Subquery with NOT EXISTS / Filtering (O(n) time, O(n) space)
Another way is to first identify products that have sales outside Q1 2019. A subquery filters rows where sale_date is before 2019-01-01 or after 2019-03-31. Any product appearing in that result set should be excluded. The outer query then selects products whose product_id does not appear in that list.
This technique relies on exclusion logic using NOT IN or NOT EXISTS. It works well when the query naturally separates "invalid" rows from valid ones. Subqueries like this frequently appear in database filtering problems and are easy to reason about during interviews.
Compared to grouping, the subquery approach expresses the logic more directly: remove products with invalid dates, then return the rest. However, some SQL engines optimize grouped aggregations better, especially when indexes exist on product_id or sale_date.
Recommended for interviews: The JOIN + GROUP BY solution is usually preferred because it demonstrates strong understanding of GROUP BY aggregation and conditional filtering. The subquery version is also valid and sometimes easier to write quickly. Showing both approaches demonstrates good SQL reasoning and awareness of multiple query strategies.
Approach 1: Using SQL JOIN and GROUP BY
This approach involves using SQL to join the Product and Sales tables on the product_id column. We filter the sales to include only those made in the first quarter of 2019 and use GROUP BY to ensure the product was sold only during this period. We left join again to ensure there are no sales for these products outside this period.
This Python solution uses Panda's DataFrame to filter sales within the first quarter of 2019 and excludes any products sold outside this period. It then finds products only sold in the specified period by subtracting sets of product IDs.
Code
Python
JavaScript
Complexity
Time Complexity: O(n + m), where n is the number of rows in the Product table and m is the number in the Sales table. Space Complexity: O(n + m) for storing filter results.
Approach 2: Using SQL Subquery
This approach involves using a subquery to find product IDs that have sales exclusively in the first quarter of 2019. We first identify sales in this period and ensure there are no other sales for these products outside this period using NOT EXISTS with filtered sales.
This SQL solution uses a subquery to verify that the product was sold in Q1 2019 and ensures no sales exist for the product outside this period.
Code
SQL
Complexity
Time Complexity: O(n*m), Space Complexity: O(1) when using database indexing.
Approach 3: Default Approach
Code
MySQL
Complexity Comparison
| Approach | Complexity |
|---|---|
| Using SQL JOIN and GROUP BY | Time Complexity: O(n + m), where n is the number of rows in the Product table and m is the number in the Sales table. Space Complexity: O(n + m) for storing filter results. |
| Using SQL Subquery | Time Complexity: O(n*m), Space Complexity: O(1) when using database indexing. |
| Default Approach | — |
Detailed Complexity Analysis
| Approach | Time | Space | When to Use |
|---|---|---|---|
| JOIN + GROUP BY with MIN/MAX date checks | O(n) | O(n) | Best when validating constraints across grouped records |
| Subquery exclusion using NOT IN / NOT EXISTS | O(n) | O(n) | Useful when you can isolate invalid rows and filter them out |
Video Solution
LeetCode 1084: Sales Analysis III [SQL] • Frederik Müller • 5,331 views views
Watch 9 more video solutions →Frequently Asked Questions
Is Sales Analysis III easy or hard?
Sales Analysis III Python/Java solution
How to solve Sales Analysis III in O(n)?
What is the best approach for Sales Analysis III?
Is Sales Analysis III asked at Google/Amazon/Meta?
What data structure is used in Sales Analysis III?
What is the time complexity of Sales Analysis III?
Ready to solve this problem?
Practice Sales Analysis III with our built-in code editor and test cases.
Practice on FleetCodeTable of Contents
Practice this problem
Open in Editor