A real database running in your browser. Refresh your SQL before a technical support / analyst interview — no signup, nothing to install.
🎮 built by TechLexicon
🚀 This is already a planned game inside TechLexicon (releasing after our public launch). I built this standalone version so you can start prepping for your interview right now — the in-app version will add leveled challenges, more databases, and rewards.
💡 How to use this
Skim the sample database below — it's the tables you'll query.
Use the tabs to switch between Practice (write & run queries), Interview Questions (the "explain it out loud" kind), and Tips.
Tap 📝 Cheat Sheet anywhere — next to the playground or on any challenge — to pop up the quick reference without scrolling.
Try each challenge yourself before hitting "Show solution." Everything runs locally; nothing is sent anywhere.
Senior-level SQL. Great if your interview goes past the basics — window functions and 3-table joins are common differentiators.
💬 Conceptual questions they may ask out loud
These don't need a query — practice explaining each in one or two clear sentences.
🎤 Interview tips (support-role SQL)
Think out loud. Support/analyst interviewers care how you reason, not just the final query.
Clarify the schema first. "Which table has the resolution timestamp? Can an account have zero tickets?" — asking is a plus.
Know your JOIN types. INNER vs LEFT is the most common gotcha. "Find accounts with no tickets" = LEFT JOIN + IS NULL.
WHERE vs HAVING. WHERE filters rows before grouping; HAVING filters groups after.
Handle NULLs. Open tickets have resolved_at IS NULL — use IS NULL, never = NULL.
Start simple, then layer. Get a SELECT working, then add filters, joins, and aggregation step by step.
🎯 Do a live mock interview too. This tool warms up the fundamentals, but nothing beats running through questions out loud with a friend or peer. Ask around — most people are glad to help.
🚀 Want to keep leveling up? TechLexicon turns tech, cloud, DevOps, databases & security into games instead of textbooks.
📝 SQL Cheat Sheet
-- Filter rows
SELECT col1, col2 FROM table
WHERE priority = 'High' AND status <> 'Closed';
-- Sort + limit
SELECT * FROM tickets
ORDER BY created_at DESC LIMIT 5;
-- Aggregate + group
SELECT status, COUNT(*) AS n
FROM tickets GROUP BY status;
-- HAVING filters AFTER grouping (WHERE filters BEFORE)
SELECT account_id, COUNT(*) AS n
FROM tickets GROUP BY account_id
HAVING COUNT(*) > 3;
-- JOINs
SELECT t.subject, a.name
FROM tickets t
JOIN accounts a ON a.id = t.account_id; -- INNER = matches only
-- LEFT JOIN keeps ALL left rows; unmatched right = NULL
-- NULL handling
WHERE resolved_at IS NULL -- not "= NULL"
COALESCE(resolved_at, 'open') -- default if NULL
-- Subquery
SELECT * FROM tickets
WHERE account_id IN
(SELECT id FROM accounts WHERE plan='Enterprise');
-- Dates (SQLite)
WHERE created_at >= date('now','-30 days');
julianday(resolved_at) - julianday(created_at) -- difference in days
-- Window functions (SQLite 3.25+)
ROW_NUMBER() OVER (PARTITION BY account_id ORDER BY created_at DESC)
RANK() / DENSE_RANK() OVER (ORDER BY total DESC)
COUNT(*) OVER (ORDER BY created_at) -- running total
LAG(col) OVER (PARTITION BY x ORDER BY y) -- previous row's value
-- CTE (a named, reusable subquery)
WITH resolved AS (
SELECT account_id,
julianday(resolved_at) - julianday(created_at) AS days
FROM tickets WHERE resolved_at IS NOT NULL
)
SELECT account_id, AVG(days) FROM resolved GROUP BY account_id;