
You don’t learn SQL by reading about it. You learn it by typing a query, running it, and looking at what comes back — then changing one thing and running it again. My SQL practice lab on GitHub is built for exactly that: two real databases, 100 questions from your first SELECT to interview-level window functions, and the expected result written under every answer.
Every answer was run against the real data, and there’s a script in the repo that re-checks all 100 in one go. Nothing to install except a free app, and no account or server needed.
What’s in the lab
| Database | What it is | Size | Questions |
|---|---|---|---|
| Chinook | A digital music store: artists, albums, tracks, customers, invoices and staff | 11 tables, 15,607 rows, about 1 MB | 60 |
| Employees | A company with 300,024 people and 17 years of job titles, departments and salaries | 6 tables, 3.9 million rows, about 300 MB | 40 |
Start with Chinook — it’s small and easy to picture. Move to Employees when you want to feel what real table sizes are like. Both are single SQLite files, so there’s no database server to set up.
Set it up in about ten minutes
- Download the two databases from the repo’s latest release (
chinook-sqlite.zip, 0.4 MB, andemployees-sqlite.zip, 81 MB) and the practice files (the repo as a ZIP, orgit cloneit). Unzip everything and put the two database files in thedatabasesfolder. - Install DBeaver Community — free and open source, for Windows, macOS and Linux. Package managers work too:
choco install dbeaveron Windows,brew install --cask dbeaver-communityon a Mac. - Connect to Chinook: click New Database Connection (the plug icon with a plus), search for SQLite, click Next, choose
Chinook_Sqlite.sqlitenext to Path, and click Test Connection. The first time, DBeaver offers to download the SQLite driver — click Download, then Finish. - Connect to Employees the same way, choosing
employees_db-full-1.0.6.db. - Run your first query: File → Open File…, open
practice/chinook.sql, click the< N/A >box in the toolbar and pick the Chinook connection. Then click inside a query and press Ctrl + Enter (⌘ + Enter on a Mac).
Run one query at a time with Ctrl + Enter. The other run button, Alt + X, runs the whole file and opens sixty result tabs.
Two ways to practice
- Learn by example:
practice/chinook.sqlandpractice/employees.sqlhave each question followed by its answer and the expected result. Run it, change it, break it, see what happens. - Test yourself: the files in
practice/quiz/have only the questions, a hint and aCheck:line. Write your own query, then compare your result with the check.
Here’s what a question looks like — number 40, a four-table join:
-- Q40. Which 10 artists earned the most revenue?
SELECT ar.Name AS Artist,
ROUND(SUM(il.UnitPrice * il.Quantity), 2) AS Revenue
FROM InvoiceLine il
JOIN Track t ON t.TrackId = il.TrackId
JOIN Album al ON al.AlbumId = t.AlbumId
JOIN Artist ar ON ar.ArtistId = al.ArtistId
GROUP BY ar.ArtistId, ar.Name
ORDER BY Revenue DESC, ar.Name
LIMIT 10;
-- Result: 10 rows. First row: Iron Maiden | 138.6

What each level covers
| Chinook level | Questions | You practice |
|---|---|---|
| 1. SELECT basics | Q1–Q10 | SELECT, LIMIT, DISTINCT, ORDER BY, aliases |
| 2. Filtering | Q11–Q20 | WHERE, IN, BETWEEN, LIKE, IS NULL |
| 3. Totals and groups | Q21–Q30 | COUNT, SUM, AVG, GROUP BY, HAVING |
| 4. JOINs | Q31–Q40 | Inner and left joins, three- and four-table joins, a self-join |
| 5. Subqueries and CTEs | Q41–Q50 | Subqueries, WITH, CASE, UNION, dates, COALESCE |
| 6. Window functions | Q51–Q60 | ROW_NUMBER, RANK, NTILE, LAG, running totals, top N per group |
The 40 Employees questions go from warm-ups on big tables, through counting at scale and joins across up to five tables, to advanced analysis: top N per group, pivots with CASE, date maths, a recursive CTE and a median.
One rule unlocks most of the Employees questions: a to_date of '9999-01-01' means “still true today”. Add it to your WHERE to get someone’s current salary, title or department; leave it out to see the whole history. And add LIMIT 10 while you’re exploring — the salaries table alone has 2.8 million rows.
SQLite habits worth knowing
SQL is almost the same everywhere, but every database has a few habits of its own:
| You want to | In SQLite you write |
|---|---|
| Join text together | FirstName || ' ' || LastName |
| Get only the first rows | LIMIT 10 at the end (not TOP 10) |
| Divide without losing decimals | Milliseconds / 60000.0 — with the .0 |
| Get the year of a date | strftime('%Y', InvoiceDate) |
| Count days between two dates | julianday(end_date) - julianday(start_date) |
| Replace a missing value | COALESCE(Company, 'Individual') |
| Find missing values | Company IS NULL (never = NULL) |
Why testers need this too
If you work in QA or as an SDET, SQL is how you check what the application actually saved — not just what the screen said. The database step in my Java test automation framework does exactly that over JDBC, and every query you practise here is one you can drop into a test.
Check every answer yourself
With Python 3 installed and the databases in place, one command re-runs all 100 answers against the real data:
python tools/check_answers.py
Common problems
- “No such table”. Check the database box in the toolbar matches the file you have open, and remember Chinook’s table names are singular:
Track, notTracks. - “No active connection”. The file isn’t linked to a database yet — click the
< N/A >box and pick one. - Only 200 rows show. DBeaver loads 200 at a time to stay fast; scroll to the bottom for more, or use
COUNT(*)to get the total. - Some Employees queries take a few seconds. That’s normal with millions of rows.
Frequently asked questions
Can I break the database?
Not with SELECT — reading never changes data. If you experiment with INSERT, UPDATE or DELETE, unzip the database again for a fresh copy.
Will this work for MySQL, PostgreSQL or SQL Server?
Almost all of it. SELECT, JOIN, GROUP BY, subqueries, CTEs and window functions are standard SQL; the few SQLite habits are in the table above. For practice on a MySQL server, see my guide to running your own MySQL with XAMPP and DBeaver.
Do I have to use DBeaver?
No. The databases are plain SQLite files, so DB Browser for SQLite, the sqlite3 command line or an editor extension all work.
Credits
The lab stands on databases other people made and shared. Chinook is by Luis Rocha (lerocha/chinook-database, MIT license). The Employees data is by Fusheng Wang and Carlo Zaniolo, with the schema by Giuseppe Maxia, the export by Patrick Crews and the SQLite port by Peter Reutemann (fracpete/employees-db-sqlite, CC BY-SA 3.0). Both are shared unchanged, with their licenses, in the release downloads.
Questions, answers and the step-by-step guide with screenshots: sql-practice-lab on GitHub.
