▸_sqlgym

Master the SQL that interviews actually test

A LeetCode-style gym of 101+ problems spanning every corner of SQL — joins, aggregation, subqueries, set ops, CTEs & recursion, window functions, ranking, pivoting, dates, strings and NULL logic. Every query runs live in your browser on a real SQLite engine, and each ships a worked solution with a step-by-step explanation.

101 problems
#TitleDifficulty
1Generate a Number Sequence
WITH RECURSIVEanchor + recursive memberRecursive CTEs
Easy
2Running Total of Sales
SUM() OVERORDER BY frameWindow Functions
Easy
3Above-Average Spenders
multiple CTEsaggregate then compareCTEs
Medium
4Second Highest Salary (DENSE_RANK)
DENSE_RANKfilter on rankRanking
Medium
5Customers Who Bought Every Product
relational divisionCOUNT(DISTINCT)HAVINGAdvanced Filtering
Hard
6Custom Priority Sort
CASE in ORDER BYcustom collation orderOrdering
Medium
7Employee Hierarchy Levels
WITH RECURSIVEhierarchylevel counterRecursive CTEs
Medium
83-Day Moving Average
AVG() OVERROWS BETWEEN frameWindow Functions
Medium
9Filter, Then Compare Within a CTE
CTE filteringself-reference for aggregateCTEs
Medium
10Top 2 Products per Category
ROW_NUMBERPARTITION BYtop-N-per-groupRanking
Medium
11Find Duplicate Emails
GROUP BYHAVING COUNTAdvanced Filtering
Easy
12Sort With NULLs Last
NULL orderingexpression sort keyOrdering
Medium
13Build the Org Path
WITH RECURSIVEstring accumulationpathRecursive CTEs
Medium
14Month-over-Month Change
LAG()previous-row accessWindow Functions
Medium
15Category Revenue Leaders
chained CTEsjoin CTE to CTEratio thresholdCTEs
Hard
16RANK vs DENSE_RANK
RANKDENSE_RANKtie handlingRanking
Easy
17Second Highest, No LIMIT
correlated subqueryMAX of a filtered setAdvanced Filtering
Medium
18Order by Best Value
computed sort keyCASTalias in ORDER BYOrdering
Easy
19Fill the Date Gaps
WITH RECURSIVEcalendar generationLEFT JOINRecursive CTEs
Hard
20Percent of Category Total
SUM() OVER PARTITION BYratio to group totalWindow Functions
Medium
21Highest and Lowest Earner
ORDER BY + LIMIT inside a CTEUNION ALLfinal orderingCTEs
Medium
22Consecutive Login Streaks (Gaps & Islands)
ROW_NUMBERgaps and islandsgrouping trickRanking
Hard
23Customers With No Orders
anti-joinNOT EXISTSAdvanced Filtering
Easy
24Multi-Key Ordering
multiple sort keysmixed ASC/DESCOrdering
Easy
25Fibonacci Sequence
WITH RECURSIVEcarried statemultiple accumulatorsRecursive CTEs
Medium
26First and Last Close per Symbol
FIRST_VALUELAST_VALUEexplicit frame gotchaWindow Functions
Hard
27Score Quartiles with NTILE
NTILEbucketingRanking
Medium
28Departments Above Average Headcount
aggregate of aggregatessubquery in WHEREAdvanced Filtering
Medium
29Difference From Subject Average
AVG() OVER PARTITION BYrow vs group comparisonWindow Functions
Medium
30Employee and Their Manager
INNER JOINself-joinJoins
Easy
31Every Product and Units Sold
LEFT JOINCOALESCEGROUP BYJoins
Easy
32Headcount per Department
INNER JOINGROUP BYCOUNTJoins
Easy
33Assign Letter Grades (Band Join)
non-equi joinBETWEENrange lookupJoins
Medium
34Customers Who Placed Orders
semi-joinEXISTSINJoins
Medium
35Customers Without Orders
anti-joinNOT EXISTSLEFT JOIN ... IS NULLJoins
Medium
36Size × Color Product Matrix
CROSS JOINCartesian productJoins
Medium
37Warmer Than the Previous Day
self-joinnon-equi joindate arithmeticJoins
Medium
38All Students and All Memberships
FULL OUTER JOINNULLS LASTunmatched rowsJoins
Hard
39Coworker Pairs in the Same Department
self-joinpair generationdeduplicate A-B/B-AJoins
Hard
40Spend per Customer Across Three Tables
three-table joinGROUP BYSUMJoins
Hard
41Distinct Products Per Store
COUNT(DISTINCT)GROUP BYAggregation
Easy
42Orders Per Customer
GROUP BYCOUNTAggregation
Easy
43Revenue By Category
GROUP BYSUMAVGAggregation
Easy
44Big Spenders (HAVING Threshold)
GROUP BYHAVINGSUMAggregation
Medium
45Grade Distribution By Class
GROUP BY multiple columnsCOUNTAggregation
Medium
46Paid vs Unpaid Invoices
conditional aggregationCASEFILTERAggregation
Medium
47Pass Rate Per Quiz
ratio of subgroup to totalconditional aggregationAVGAggregation
Medium
48Tags Per Post (Ordered List)
group_concatordered aggregationGROUP BYAggregation
Medium
49Department Payroll (Aggregate Over Join)
aggregate over joinJOINGROUP BYAggregation
Hard
50Favorite Genre Per User (Mode)
modemost-frequent valueCOUNTAggregation
Hard
51Weighted Course GPA
weighted averageSUMROUNDAggregation
Hard
52Order Count Per Customer (Scalar Subquery)
scalar subquerysubquery in SELECTcorrelated subquerySubqueries
Easy
53Orders Above the Overall Average
comparison to scalar subqueryAVGsubquery in WHERESubqueries
Easy
54Books by Prolific Authors (Uncorrelated Subquery Filter)
uncorrelated subqueryINGROUP BYSubqueries
Medium
55Customers With a Big Order (IN vs EXISTS)
INEXISTSsemi-joinSubqueries
Medium
56Products Priced Above Their Category Average
correlated subquerysubquery in WHEREAVGSubqueries
Medium
57Top Spenders via a Derived Table
derived tablesubquery in FROMGROUP BYSubqueries
Medium
58Departments Beating the Company Average (HAVING + Subquery)
subquery in HAVINGAVGGROUP BYSubqueries
Hard
59Each Customer's Most Expensive Order
greatest-n-per-groupcorrelated subqueryMAXSubqueries
Hard
60All People Across Two Tables (UNION dedupe)
UNIONdeduplicationORDER BYSet Operations
Easy
61Customers Who Bought on Both Channels (INTERSECT)
INTERSECTdeduplicationORDER BYSet Operations
Easy
62Churned Customers (EXCEPT)
EXCEPTanti-joindeduplicationSet Operations
Medium
63UNION ALL vs UNION: Counting Logins
UNION ALLUNIONduplicatesSet Operations
Medium
64Items on Exactly One Menu (Symmetric Difference)
symmetric differenceEXCEPTUNIONSet Operations
Hard
65Signup Funnel Conversion
CTE chainingFunnelConversion rateCTEs
Medium
66Everyone Who Reports Up To A Manager
Recursive CTETransitive ClosureGraphRecursive CTEs
Hard
67Split CSV Tags Into Rows
Recursive CTEString SplitSUBSTRRecursive CTEs
Hard
68Exam Score Percentile
CUME_DISTPERCENT_RANKWindow FunctionsWindow Functions
Medium
69Gap To Next Login
LEADWindow FunctionsDate DiffWindow Functions
Medium
70Running Maximum Balance
MAX OVERRunning AggregateWindow FunctionsWindow Functions
Medium
71Daily Cumulative Sales (RANGE vs ROWS)
RANGE frameROWS frameWindow FunctionsWindow Functions
Hard
72Deduplicate Keeping Latest Contact
ROW_NUMBERDeduplicationRankingRanking
Medium
73Top Scorers With Ties
RANKTop-N with tiesRankingRanking
Medium
74Median Home Price
ROW_NUMBERMedianRankingRanking
Hard
75Pivot Order Status Counts
conditional aggregationCOUNTSUMPivoting
Medium
76Pivot Quarterly Sales into Columns
conditional aggregationSUMCASEPivoting
Medium
77Unpivot Subject Scores into Rows
UNION ALLunpivotPivoting
Medium
78Binary Skill Presence Matrix
conditional aggregationMAXCASEPivoting
Hard
79Pivot Months then Add a Total
conditional aggregationSUMderived columnPivoting
Hard
80Two-Dimensional Pivot: Store by Quarter
conditional aggregationtwo-dimensional pivotSUMPivoting
Hard
81Days Between Subscription Dates
juliandayDates & Time
Easy
82Extract Year, Month, and Weekday
strftimeDates & Time
Easy
83Weekend Events Only
strftimeweekday filterDates & Time
Easy
84Age in Whole Years
strftimewhole-year ageDates & Time
Medium
85Count Events Per Month
strftimeGROUP BY monthDates & Time
Medium
86First and Last Day of Each Month
date modifiersstart of monthDates & Time
Medium
87Orders in the Last 30 Days
date arithmeticreference dateDates & Time
Medium
88Events Per Weekday Name
strftimeweekday mappingGROUP BYDates & Time
Hard
89Build a Full Name
concatenation||String Manipulation
Easy
90Case-Insensitive Product Search
lowerLIKEString Manipulation
Easy
91Clean Phone Numbers with replace
replaceString Manipulation
Easy
92Count Items in a CSV Field
lengthreplaceString Manipulation
Medium
93Extract the Email Domain
substrinstrString Manipulation
Medium
94Format Prices with printf
printfString Manipulation
Medium
95Avoid Divide-by-Zero with NULLIF
NULLIFCOALESCENULL Handling
Easy
96Default Missing Values with COALESCE
COALESCEIFNULLNULL Handling
Easy
97COUNT(*) vs COUNT(column) and AVG over NULLs
COUNT(*)COUNT(col)AVG ignores NULLNULL Handling
Medium
98IS NULL, IS NOT NULL, and Three-Valued Logic
IS NULLIS NOT NULLthree-valued logicNULL Handling
Medium
99The NOT IN NULL Trap
NOT EXISTSNOT IN pitfallthree-valued logicNULL Handling
Hard
100Bought Product X But Not Product Y
EXISTSNOT EXISTSAnti-joinAdvanced Filtering
Medium
101Case-Insensitive Name Sort
COLLATE NOCASEgroup_concatDeterministic orderOrdering
Medium