SQL Practice Online with 36 Graded Exercises
Graded SQL exercises and a free-query playground on SQLite in your browser
All products
Return the name and price of every product.
Show the schema
customers
- customer_idINTEGERprimary key
- first_nameTEXT
- last_nameTEXT
- emailTEXTnullable
- cityTEXTnullable
- countryTEXT
- signup_dateTEXTYYYY-MM-DD
orders
- order_idINTEGERprimary key
- customer_idINTEGERFK customers
- employee_idINTEGERFK employees (sales rep)
- order_dateTEXTYYYY-MM-DD
- statusTEXTpending | shipped | delivered | cancelled
- shipped_dateTEXTNULL until shipped
order_items
- order_idINTEGERFK orders
- product_idINTEGERFK products
- quantityINTEGER
- unit_priceREALprice at time of order
products
- product_idINTEGERprimary key
- nameTEXT
- categoryTEXTLaptops | Monitors | Accessories | Software
- priceREAL
- stockINTEGERNULL for software
employees
- employee_idINTEGERprimary key
- first_nameTEXT
- last_nameTEXT
- titleTEXT
- departmentTEXT
- salaryINTEGER
- hire_dateTEXTYYYY-MM-DD
- manager_idINTEGERFK employees, NULL for the CEO
A real database in your browser, not a quiz
This page runs SQLite, the database engine inside every phone and browser, compiled to WebAssembly (the open-source sql.js project). Your queries execute against real tables in a Web Worker on your own machine. There is no server round-trip, no account and no row limit, and nothing you type is sent anywhere. Because it is a genuine engine, error messages are SQLite's own: misspell a column and you get "no such column", forget a GROUP BY and the result tells you.
The sample database is a small online store with five tables: customers, orders, order_items, products and employees, where employees reference their manager through manager_id. The data is deterministic, so everyone sees the same rows, and it contains the awkward cases that real data has and toy examples skip: customers who never ordered, a product that never sold, NULL emails and cities, NULL stock on software, unshipped orders with no shipped_date and a CEO with no manager.
How answers are checked
Each exercise has a reference query. When you press Check answer, your query and the reference run on separate fresh copies of the database and the two result sets are compared. Column names do not matter, so alias freely, but the number and order of columns does, and so do the values. Numbers are compared to two decimal places, so AVG(price) and ROUND(AVG(price), 2) both pass. Row order is only checked when the task asks for an ORDER BY, and those tasks always name a tie-breaker so exactly one order is correct.
That means any correct query passes, not just the one in the solution. A LEFT JOIN with IS NULL, NOT EXISTS and NOT IN can all solve the never-ordered exercise. If your answer is wrong, the checker tells you whether the column count, the row count, the values or only the order differs. Because every check uses a fresh copy, a stray DELETE in one attempt cannot break the next one.
What the 36 exercises cover
The ten easy exercises cover SELECT, WHERE, BETWEEN, LIKE, IN, DISTINCT, ORDER BY with LIMIT, IS NULL and computed columns. The fourteen medium ones move to COUNT, SUM and AVG with GROUP BY and HAVING, the difference between COUNT(*) and COUNT(column), inner and left joins (including keeping customers with zero orders), a self-join from employees to their managers, date ranges on ISO dates, CASE expressions and COALESCE.
The twelve hard exercises are the topics interviewers ask about: scalar, correlated and NOT EXISTS subqueries, common table expressions, a recursive CTE that walks the reporting tree, conditional aggregation that pivots statuses into columns, and window functions: RANK and ROW_NUMBER with PARTITION BY, a running count, LAG and a share-of-total with SUM() OVER. Every exercise has a hint and a reference solution, and your progress and drafts are saved in this browser.
SQLite vs PostgreSQL, MySQL and SQL Server
Almost everything you practise here is standard SQL and works unchanged in PostgreSQL, MySQL 8 and SQL Server. A few differences matter. SQLite stores dates as text, so this database uses ISO YYYY-MM-DD strings and substr() or strftime() to extract parts, where PostgreSQL has DATE_TRUNC and EXTRACT. Integer division truncates in SQLite, PostgreSQL and SQL Server, so multiply by 100.0 when you want a percentage. SQL Server uses TOP instead of LIMIT. SQLite also allows a column in the SELECT list that is not in GROUP BY, which PostgreSQL rejects, so practise grouping by every non-aggregated column.
The Free query tab accepts any SQLite statement, including CREATE TABLE, INSERT, UPDATE and DELETE, and keeps your changes until you reset. Use it to try ideas from the SQL cheat sheet, or to test a query before formatting it with the SQL formatter.
How to use the SQL Practice Online with 36 Graded Exercises tool
- 1
Read the schema
Open the Schema tab to see the five tables and their columns, including which ones can be NULL.
- 2
Pick an exercise
Start with the easy ones or jump to a topic in the list. Each task says exactly which columns to return.
- 3
Write and check your query
Type SQL in the editor and press Check answer or Ctrl/Cmd + Enter. Use Run only to look at the data first.
- 4
Use hints, then experiment
Stuck? Show the hint, then the solution. Use the Free query tab to try variations, inserts and updates.
Frequently asked questions
Is this SQL practice site free?
Yes, with no signup and no limits. The database runs in your browser, so there is no server cost to recover. Progress is saved in your browser's local storage, which means it stays on this device and is lost if you clear site data.
Which SQL dialect does it use?
SQLite 3.49 via sql.js. The exercises stick to standard SQL (joins, GROUP BY, subqueries, CTEs, window functions) that also runs on PostgreSQL, MySQL 8 and SQL Server, apart from the date functions noted in the guide.
My query looks right but is marked wrong. Why?
Check the column count and order against the task first, then whether NULLs are handled (COUNT(column) skips them, = NULL never matches). If the message says the rows are right but the order is wrong, add the tie-breaker the task names to your ORDER BY.
Can I break the database?
No. Exercises run on a fresh copy every time, and the Free query tab has a Reset database button. A query that runs for more than four seconds, such as a recursive CTE without a stop condition, is stopped automatically.
Are these good SQL interview practice questions?
They cover the patterns that come up most: joins that keep unmatched rows, GROUP BY with HAVING, top-N per group, running totals, LAG and recursive hierarchies. For timed interview prep, solve each one without the hint first.
Related on TechLogHub
Related Formatter Tools
SQL Formatter with Uppercase Keywords
Format and beautify SQL queries with proper indentation
MongoDB Query Formatter
Format and beautify MongoDB queries
XML Formatter and Validator with Error Lines
Pretty-print, minify and validate XML, keeping comments and CDATA intact
HTML Formatter with Pre and Script Preserved
Beautify messy or minified HTML while leaving pre, script, style and textarea content untouched
Get the next tool before you need it
One email a week: new and trending developer tools, fresh comparisons, and what shipped. Unsubscribe in one click.

