SQL
Learn SQL by typing real, working queries.
Practice SQL by typing queries that run: SELECTs with filtering and sorting, every kind of JOIN, GROUP BY aggregation, subqueries, CTEs, and window functions. Each snippet is real, standard SQL, and an AI tutor explains every clause — how a LEFT JOIN keeps unmatched rows, why a window function beats a self-join — so query-writing becomes second nature as you type.
Progress0 / 242 solved · 0/19 sections
best wpm
0
avg wpm
0
accuracy
0%
runs
0
level
1
rating
1000
Run SQL on your machine
1. Install the toolchain
brew install sqlite # usually preinstalled2. Save your code as query.sql, then compile & run
sqlite3 demo.db < query.sqlprogress by section
1Queries0/14start →
2Filtering0/14start →
3Sorting & Limiting0/10start →
4Joins0/14Unlock →
5Aggregation0/14Unlock →
Count rows with COUNT(*)Total a column with SUMAverage with AVGSmallest and largest with MIN and MAXAverage within each groupHow COUNT treats NULLsAggregate per group with GROUP BYCount unique values with COUNT(DISTINCT)Join group values with group_concatGroup by several columnsFilter groups with HAVINGConditional aggregation with SUM(CASE)Per-aggregate filters with FILTERGrand-total row, rollup style
6Subqueries0/14Unlock →
Above the global averageMembership test with IN (subquery)Exclusion with NOT INScalar subquery in WHERESubquery driving a WHERE filterPresence test with EXISTSDerived table in FROMAbsence test with NOT EXISTSSubquery in the SELECT listALL-style test via a comparisonANY-style test via a comparisonCorrelated subquery per rowAggregate of an aggregateSubquery nested two levels deep
7CTEs0/12Unlock →
8Window Functions0/14Unlock →
No gaps with DENSE_RANKOrdering inside a windowTies and gaps with RANKNumber rows with ROW_NUMBERPrevious row with LAGNext row with LEADReset per group with PARTITION BYRunning total with SUM OVERFIRST_VALUE and LAST_VALUEMoving average over a frameReuse a window with WINDOWBuckets with NTILERelative standing with PERCENT_RANKTop-N per group
9Set Operations0/10Unlock →
10Schema (DDL)0/14Unlock →
11Modifying Data0/14Unlock →
12Constraints0/12Unlock →
13Indexes0/10Unlock →
14Views0/10Unlock →
15Transactions0/10Unlock →
16String Functions0/14Unlock →
17Date & Time0/14Unlock →
date, time and datetimeCURRENT_DATE and CURRENT_TIMESTAMPextract year, month and daydate arithmetic with modifiersstart of month and yearstrftime format codesadd months safelyday difference with juliandayunix epoch conversionage in whole yearsday-of-week namegroup rows by monthlast day of the monthweekday modifier
18JSON0/12Unlock →
json() validates and minifiesjson_array and json_objectjson_extract by pathjson_type inspects a valuethe -> and ->> operatorsjson_remove deletes pathsjson_each unnests an arrayjson_each over an objectjson_group_array aggregates rowsjson_set, json_insert, json_replacejson_group_object builds an objectquery a JSON column
19Query Challenges0/16Unlock →
Duplicate emailsCustomers who never orderEarning more than their managerRank scores (dense)Second-highest salaryDelete duplicate rows, keep oneFirst purchase per customerNth-highest salaryPivot rows to columnsRising temperatureRunning totalNumbers appearing 3+ times in a rowDepartment top-3 earnersTop product per categoryGaps and islandsMedian value