Filter and sort
Learn how WHERE, ORDER BY and LIMIT narrow and arrange a result set.
SELECT name, city, joined_date
FROM students
WHERE city = 'Bengaluru'
ORDER BY joined_date DESC
LIMIT 10;Open in editorFree tool
Write and run SQL against a realistic learning-platform schema — students, instructors, courses and enrollments — and practice everything from simple filters to recursive CTEs.
Powered by real Postgres, runs entirely in your browser
This SQL compiler runs PostgreSQL inside your browser tab, so you can practice the SQL used in analytics interviews and day-to-day reporting without installing a database. Use it as a PostgreSQL playground for joins, aggregations, CTEs and window functions.
Write a query, press Run, and see results instantly. There is nothing to set up and no account is needed.
| Table | Columns | What it holds |
|---|---|---|
| students | student_id SERIAL, name TEXT, email TEXT, city TEXT, track TEXT, joined_date DATE | 18 learners, their location, track and joining date. |
| instructors | instructor_id SERIAL, name TEXT, company TEXT | 5 instructors and their companies. |
| courses | course_id SERIAL, title TEXT, track TEXT, instructor_id INT, duration_weeks INT | 9 courses, their tracks, instructors and durations. |
| enrollments | enrollment_id SERIAL, student_id INT, course_id INT, enrolled_date DATE, completion_pct INT, score INT | 38 course enrollments with completion and score data. |
Courses join to instructors through instructor_id. Enrollments join to students through student_id and to courses through course_id.
Learn how WHERE, ORDER BY and LIMIT narrow and arrange a result set.
SELECT name, city, joined_date
FROM students
WHERE city = 'Bengaluru'
ORDER BY joined_date DESC
LIMIT 10;Open in editorCount enrollments for each course by joining courses to enrollments.
SELECT c.title, COUNT(e.enrollment_id) AS enrollments
FROM courses c
JOIN enrollments e ON e.course_id = c.course_id
GROUP BY c.title
ORDER BY enrollments DESC;Open in editorFind students not enrolled in a specific course by checking for an unmatched row.
SELECT s.name
FROM students s
LEFT JOIN enrollments e
ON e.student_id = s.student_id
AND e.course_id = 9
WHERE e.enrollment_id IS NULL;Open in editorFilter grouped results after counting courses for each instructor.
SELECT i.name, COUNT(c.course_id) AS course_count
FROM instructors i
JOIN courses c ON c.instructor_id = i.instructor_id
GROUP BY i.name
HAVING COUNT(c.course_id) >= 2;Open in editorTurn numeric course durations into clear learning bands.
SELECT title,
duration_weeks,
CASE
WHEN duration_weeks <= 3 THEN 'Short'
WHEN duration_weeks <= 4 THEN 'Standard'
ELSE 'Extended'
END AS duration_band
FROM courses
ORDER BY duration_weeks, title;Open in editorBreak an aggregation into a named step before joining it to course details.
WITH course_counts AS (
SELECT course_id, COUNT(*) AS enrollments
FROM enrollments
GROUP BY course_id
)
SELECT c.title, cc.enrollments
FROM course_counts cc
JOIN courses c ON c.course_id = cc.course_id
ORDER BY cc.enrollments DESC
LIMIT 3;Open in editorRank courses within each instructor without collapsing the course rows.
SELECT i.name AS instructor,
c.title,
COUNT(e.enrollment_id) AS enrollments,
RANK() OVER (
PARTITION BY i.instructor_id
ORDER BY COUNT(e.enrollment_id) DESC
) AS rank_in_instructor
FROM instructors i
JOIN courses c ON c.instructor_id = i.instructor_id
LEFT JOIN enrollments e ON e.course_id = c.course_id
GROUP BY i.instructor_id, i.name, c.course_id, c.title
ORDER BY instructor, rank_in_instructor;Open in editorCompare each month’s enrollment count with the previous month.
WITH monthly AS (
SELECT DATE_TRUNC('month', enrolled_date) AS month,
COUNT(*) AS enrollments
FROM enrollments
GROUP BY 1
)
SELECT month,
enrollments,
enrollments - LAG(enrollments) OVER (ORDER BY month) AS change_vs_prev_month
FROM monthly
ORDER BY month;Open in editorGenerate a date series by repeatedly building on the previous row.
WITH RECURSIVE days AS (
SELECT DATE '2026-01-01' AS day
UNION ALL
SELECT day + 1 FROM days WHERE day < DATE '2026-01-10'
)
SELECT day FROM days;Open in editorA free, browser-based PostgreSQL playground. You write SQL, run it against a sample learning-platform database with students, instructors, courses and enrollments, and see the results instantly.
Yes. It uses PGlite, a build of PostgreSQL compiled to WebAssembly, so you get real Postgres syntax, including window functions, CTEs and recursive queries.
No. Open the page and start running queries. No account and no installation are needed.
No. Queries run inside your browser tab. Analytics records only whether a SQL tool run succeeds or fails, never your query or results.
Not automatically. Use the Share button to get a link that contains your query after the # symbol, or copy it before you close the tab.
Filtering and sorting, joins, GROUP BY and HAVING, subqueries, CASE expressions, CTEs, window functions such as RANK and LAG, and recursive CTEs.
Yes. Start with the example queries on this page, then try the 25 problems on our SQL Interview Questions page, which come with a live editor.
Our live cohorts take you from SQL fundamentals to dashboards, agentic analytics workflows and interview-ready case studies — with mentor feedback on every project.