Skip to main content

Sales Analysis III - Solution & Explanation

EasyDatabase6 min readAsked at: Amazon, Google, Bloomberg
Practice this problem

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.

Try this approach in the editor →

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.

Try this approach in the editor →

Approach 3: Default Approach

Code

MySQL

Try this approach in the editor →

Complexity Comparison

ApproachComplexity
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

ApproachTimeSpaceWhen to Use
JOIN + GROUP BY with MIN/MAX date checksO(n)O(n)Best when validating constraints across grouped records
Subquery exclusion using NOT IN / NOT EXISTSO(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 is rated Easy because the logic centers around simple SQL filtering and grouping. Once you recognize that a product must not have sales outside Q1 2019, the query can be implemented with straightforward aggregation or a subquery.
Sales Analysis III Python/Java solution
The problem itself is a SQL database problem, but platforms often categorize the approach under languages like Python or JavaScript that execute SQL queries. The core logic remains a SQL query using JOIN, GROUP BY, or a filtering subquery.
How to solve Sales Analysis III in O(n)?
Scan the Sales table and group records by product_id. Use aggregate functions like MIN(sale_date) and MAX(sale_date) to determine the earliest and latest sale for each product. If both dates fall between 2019-01-01 and 2019-03-31, the product qualifies.
What is the best approach for Sales Analysis III?
The most common solution uses SQL JOIN with GROUP BY and date aggregation. By grouping sales by product_id and checking that MIN(sale_date) >= '2019-01-01' and MAX(sale_date) <= '2019-03-31', you guarantee all sales occurred in Q1 2019. This approach scans the sales table once and relies on efficient aggregation.
Is Sales Analysis III asked at Google/Amazon/Meta?
The exact problem may not appear frequently, but the pattern is common in SQL interview rounds. Many companies ask questions about filtering grouped data, validating date ranges, and excluding records using subqueries or aggregations.
What data structure is used in Sales Analysis III?
The solution relies on relational database operations rather than traditional data structures. SQL engines internally use hash tables or sorting mechanisms to perform GROUP BY aggregations and joins efficiently.
What is the time complexity of Sales Analysis III?
Both common SQL solutions run in O(n) time where n is the number of rows in the Sales table. The database scans the table and either aggregates rows by product or filters them using a subquery. Space complexity is typically O(n) for grouping or intermediate query results.

Ready to solve this problem?

Practice Sales Analysis III with our built-in code editor and test cases.

Practice on FleetCode