MySQL 1633.sql
SELECT contest_id, ROUND(100 * COUNT(*) / (SELECT COUNT(DISTINCT user_id) FROM Users ), 2) AS percentage
FROM Register
GROUP BY contest_id
ORDER BY percentage DESC, contest_id
Difficulty
and has an acceptance rate of about 61% (900k+ 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 computes the participation share of each contest relative to the total number of distinct users registered in the system. It aggregates registrations per contest, calculates a percentage, and orders the results to highlight the most popular contests first.
Key Steps
The query can be broken down into three logical phases: data aggregation, percentage calculation, and result ordering.
The first phase groups rows from the Register table by contest_id and counts the number of registrations per contest.
SELECT contest_id, COUNT(*) AS reg_count
FROM Register
GROUP BY contest_id
The second phase introduces a sub-query that determines the total number of unique users across the entire platform. This value is used as the denominator for the percentage computation. The ROUND function limits the output to two decimal places, ensuring a tidy presentation.
SELECT contest_id,
ROUND(100 * COUNT(*) /
(SELECT COUNT(DISTINCT user_id) FROM Users), 2) AS percentage
FROM Register
GROUP BY contest_id
The final phase sorts the derived rows first by the computed percentage in descending order, then by contest_id to provide a deterministic tie-break when percentages are equal.
ORDER BY percentage DESC, contest_id
Edge Cases Handled
When the Users table contains no rows, the sub-query returns NULL. In most SQL dialects, any arithmetic operation involving NULL yields NULL, causing the entire percentage column to be NULL. This behavior gracefully indicates that a meaningful participation metric cannot be derived without any users.
If a contest has no registrations, it does not appear in the result set because the GROUP BY clause only produces groups that contain at least one row. Consequently, contests with zero participation are omitted, which aligns with the intent to report only active contests.
The use of COUNT(DISTINCT user_id) ensures that duplicate user entries in the Users table do not inflate the denominator, preserving the integrity of the percentage calculation even if the user data contains accidental duplicates.
Performance Optimizations
The query leverages a scalar sub-query that is evaluated once, rather than recomputed for each row of the outer query. By placing the distinct user count in a separate sub-query, the database engine can cache the result, reducing redundant scans of the Users table.
The aggregation on the Register table is performed with a simple GROUP BY contest_id, which allows the optimizer to use an index on contest_id if one exists. This index can accelerate the grouping operation by avoiding a full table scan.
The final ORDER BY clause sorts on the computed percentage and then on contest_id. Because percentage is derived from the aggregation, the sorting occurs after the grouping phase, meaning the dataset being sorted is already reduced to one row per contest, minimizing the sorting workload.
Overall, the query is structured to minimize data movement: it aggregates first, computes the percentage using a pre-computed denominator, and then orders the compact result set. This sequence promotes efficient execution, especially on large datasets where the Register table may contain many rows but the number of distinct contests is comparatively small.
ELI5 - Simplified Explanation
Imagine you have a big bucket full of blocks, and each block has a name written on it to show who owns it. There are lots of different contests happening at the same time, and kids are putting their blocks into different bins to join the fun. This code is like a helpful robot helper that walks around the room to see how popular each contest is.
First, the robot looks at all the contests and counts how many blocks are in each bin to figure out how many kids joined that specific game. Then, it runs over to the main roster to count every single kid in the whole building, making sure not to count the same person twice if they are just visiting. The robot takes the number of kids in a contest and divides it by the total number of kids in the building to see what piece of the pie that contest represents. It turns that fraction into a nice percentage number and rounds it off so it is easy to read. Finally, it sorts all the contests starting with the highest percentage at the very top of the list so everyone can see which game is the biggest hit. If two games have the same percentage, the robot just puts the one with the smaller number first to keep everything tidy.
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
Similar Problems
- problem 1211: Queries Quality and Percentage
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 1327: List the Products Ordered in a Period
- 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 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