MySQL 1327.sql
SELECT p.product_name, SUM(o.unit) AS unit
FROM Products p, Orders o
WHERE p.product_id = o.product_id
AND order_date BETWEEN '2020-02-01' AND '2020-02-29'
GROUP BY p.product_name
HAVING SUM(o.unit) >= 100
Difficulty
and has an acceptance rate of about 72% (400k+ submissions).
Typical patterns to solve this problem:
- Database
AI Disclaimer
However, two years later I set up this website and used various AI tools to generate most of the walkthrough / explanations below.
See this dedicated page for more details.
Code Walkthrough
Overview
The provided SQL statement retrieves a summary of product sales for a specific two-week period in February 2020. It selects each product name together with the total number of units sold, filters the rows to the defined date range, aggregates the data by product, and finally limits the result set to products whose cumulative sales meet or exceed a threshold of one hundred units.
Key Steps
The query can be broken down into distinct logical phases, each represented by a fragment of the original statement.
SELECT p.product_name, SUM(o.unit) AS unit
In this initial phase the query defines the output columns. The product name is taken directly from the Products table, while the total units are calculated with the aggregate function SUM applied to the unit column of the Orders table. The alias unit is assigned to the aggregated value for readability.
FROM Products p, Orders o
Here the two source tables are introduced. The comma syntax creates an implicit inner join, meaning that only rows where a matching product identifier exists in both tables will be considered for further processing.
WHERE p.product_id = o.product_id
AND order_date BETWEEN '2020-02-01' AND '2020-02-29'
The WHERE clause performs two critical filters. The equality predicate links each order to its corresponding product, establishing the join condition. The BETWEEN predicate restricts the rows to those whose order_date falls on or after February 1 2020 and on or before February 29 2020, thereby defining the reporting window.
GROUP BY p.product_name
After the rows have been filtered, the GROUP BY clause aggregates them by product name. All rows sharing the same product_name are collapsed into a single result row, and the SUM function computes the total units for each group.
HAVING SUM(o.unit) >= 100
The final phase applies a post-aggregation filter. The HAVING clause evaluates the summed units for each product group and retains only those groups whose total meets or exceeds the threshold of one hundred units. This ensures that the output contains only products with significant sales volume during the period.
Edge Cases Handled
The query’s construction implicitly addresses several boundary conditions. The inclusive nature of the BETWEEN operator guarantees that orders placed exactly on the first or last day of February 2020 are counted, preventing accidental omission of edge-date transactions. The join condition p.product_id = o.product_id ensures that orders lacking a corresponding product entry are excluded, which protects against orphaned order records that could otherwise distort the aggregation. The HAVING clause uses a greater-than-or-equal comparison, so a product with precisely one hundred units sold is retained, handling the case where the total equals the threshold.
Performance Optimizations
Although the query employs the older comma-style join syntax, modern relational engines rewrite it internally to an explicit inner join, allowing the optimizer to choose the most efficient join strategy. The presence of an equality predicate on product_id enables the use of an index on that column in both the Products and Orders tables, reducing the cost of locating matching rows. The date range filter on order_date can be satisfied by an index on the Orders table’s order_date column, allowing the engine to quickly prune rows outside the February window before the join occurs. Grouping by product_name benefits from any existing index on that column, which can accelerate the grouping operation by providing pre-sorted input. Finally, the HAVING clause is evaluated after aggregation, allowing the engine to discard low-volume groups early in the processing pipeline, thereby limiting the amount of data that must be materialized for the final result set.
ELI5 - Simplified Explanation
Imagine a big toy store that keeps two special notebooks. The first notebook has a list of every toy with a secret number to identify it. The second notebook keeps track of every time someone buys a toy, writing down which toy was picked and how many were taken.
To find the most popular toys, this code acts like a helper who looks through both notebooks at the same time. First, the helper finds the matching secret numbers so it knows exactly which toy was sold. Since the store only wants to know about toys bought in February, the helper skips any sales that happened in other months.
Next, the helper gathers all the sales for each toy and adds up the numbers to see the grand total for the whole month. Finally, the helper looks at the pile of totals and sets aside the toys that sold ten or more times so the toy store knows which ones were the big winners.
Code Quality
Complexity Analysis
Other Solutions
Obviously, I did that after I solved the problem myself.
In general, AlgoMonster and WalkCCC solutions are high-quality and always worth a look.
I haven't checked most of the other solutions, but they might be helpful as well.
And of course, the LeetCode forum is always a good place (or even the best) to look for alternative approaches.
(click on a column header to sort the table)
| author | ||||||
|---|---|---|---|---|---|---|
| author | solutions | |||||
| www | AlgoMonster | C++ | Java | Python | TS | |
| WalkCCC | SQL | |||||
| leetcode.ca | SQL | |||||
| Progiez | C++ | Java | Python | |||
| github | suxrobGM | SQL | ||||
| AlgoMonster | C++, Python, Java, TypeScript | |||||
| WalkCCC | SQL | |||||
| leetcode.ca | SQL | |||||
| Progiez | C++, Java, Python | |||||
| suxrobGM | SQL |
Videos
Solved On The Same Day
- problem 415: Add Strings
- problem 463: Island Perimeter
- problem 541: Reverse String II
- problem 1211: Queries Quality and Percentage
- problem 1251: Average Selling Price
- problem 1280: Students and Examinations
- problem 1378: Replace Employee ID With The Unique Identifier
- problem 1407: Top Travellers
- problem 1484: Group Sold Products By The Date
- problem 1517: Find Users With Valid E-Mails
- problem 1527: Patients With a Condition
- problem 1581: Customer Who Visited but Did Not Make Any Transactions
- problem 1587: Bank Account Summary II
- problem 1633: Percentage of Users Attended a Contest
- problem 1661: Average Time of Process per Machine
- problem 1667: Fix Names in a Table
- problem 1683: Invalid Tweets
- problem 1693: Daily Leads and Partners
- problem 1729: Find Followers Count
- problem 1731: The Number of Employees Which Report to Each Employee
- problem 1741: Find Total Time Spent by Each Employee
- problem 1757: Recyclable and Low Fat Products
- problem 1789: Primary Department for Each Employee
- problem 1795: Rearrange Products Table
- problem 1873: Calculate Special Bonus
- problem 1890: The Latest Login in 2020
- problem 1965: Employees With Missing Information
- problem 1978: Employees Whose Manager Left the Company
- problem 2356: Number of Unique Subjects Taught by Each Teacher
- problem 166: Fraction to Recurring Decimal
- problem 223: Rectangle Area
- problem 240: Search a 2D Matrix II
- problem 318: Maximum Product of Word Lengths
- problem 357: Count Numbers with Unique Digits
- problem 394: Decode String
- problem 1158: Market Analysis I
- problem 1341: Movie Rating
- problem 1492: The kth Factor of n
- problem 1498: Number of Subsequences That Satisfy the Given Sum Condition
- problem 1907: Count Salary Categories
- problem 1934: Confirmation Rate
- problem 2405: Optimal Partition of String
Extra
- Tech Stack - my development environment and tools
- AI - how AI helped me create this website (NOT solving the problems)
- Progress - progression over time
- Quality - code quality