Interactive learning platform with 100+ real-world queries, performance optimization tools, and hands-on sandbox
Comprehensive features designed to take your SQL skills to the next level
From basic SELECTs to advanced window functions, recursive CTEs, and JSON operations.
Explore QueriesVisual query plans, indexing strategies, and optimization tips for every query.
Optimize NowPractice with real data, test transactions, and visualize results instantly.
Try SandboxMaster ROW_NUMBER(), RANK(), running totals, and more with visual explanations.
Learn MoreReady-to-use templates for common patterns like gaps/islands, rolling totals, and more.
Get RecipesLearn SQL injection prevention, role-based access, and audit trails.
Secure Your SQLMaster the fundamental building blocks of SQL queries.
Retrieve data from a single table
Filter rows based on conditions
Sort query results
Aggregate data
Filter grouped data
Conditional logic in queries
SELECT employee_id, first_name, last_name, salary
FROM employees
WHERE department = 'Sales'
ORDER BY salary DESC
LIMIT 10;
Learn how to combine data from multiple tables.
Match rows from both tables
All rows from left table
All rows from right table
All rows from both tables
Cartesian product
Join a table to itself
SELECT e.employee_id, e.first_name, e.last_name, d.department_name
FROM employees e
INNER JOIN departments d ON e.department_id = d.department_id
WHERE d.location = 'New York'
ORDER BY e.last_name;
Queries within queries for powerful data retrieval.
Filter with subquery results
Use subquery as table
Subquery as column
Test for row existence
Reference outer query
Nested subqueries
SELECT employee_id, first_name, last_name, salary
FROM employees e
WHERE salary > (
SELECT AVG(salary)
FROM employees
WHERE department_id = e.department_id
)
ORDER BY department_id, salary DESC;
Perform calculations across sets of rows related to the current row.
Unique sequential numbers
Rank with gaps
Rank without gaps
Access adjacent rows
SUM() OVER()
Window frames
SELECT
employee_id,
first_name,
last_name,
salary,
department_id,
RANK() OVER(PARTITION BY department_id ORDER BY salary DESC) as dept_salary_rank,
salary - LAG(salary, 1, 0) OVER(PARTITION BY department_id ORDER BY salary) as salary_diff
FROM employees
ORDER BY department_id, salary DESC;
The query is performing a sequential scan on the employees table. Consider adding an index on the salary column.
CREATE INDEX idx_employees_salary ON employees(salary);
Estimated improvement: 85% faster execution
Original query performed full table scans on orders, order_items, and products tables with complex JOINs and subqueries.
Query time reduced from 8.2 seconds to 120ms (98.5% improvement)
| employee_id | first_name | last_name | department_name |
|---|---|---|---|
| 101 | John | Smith | Engineering |
| 102 | Sarah | Johnson | Marketing |
| 103 | Michael | Williams | Sales |
| 104 | Emily | Brown | Engineering |
| 105 | David | Jones | HR |
| Execution Time | 0.02 ms |
|---|---|
| Planning Time | 0.12 ms |
| Total Cost | 49.90 |
| Rows Processed | 200 |
| Shared Hit Blocks | 42 |
WITH ranked_employees AS (
SELECT
employee_id,
first_name,
last_name,
salary,
department_id,
RANK() OVER(PARTITION BY department_id ORDER BY salary DESC) as rank
FROM employees
)
SELECT * FROM ranked_employees
WHERE rank <= 3;
SELECT
first_name,
last_name,
email,
COUNT(*) as duplicate_count
FROM employees
GROUP BY first_name, last_name, email
HAVING COUNT(*) > 1;
WITH date_ranges AS (
SELECT
date,
date - ROW_NUMBER() OVER(ORDER BY date) as grp
FROM sales_dates
)
SELECT
MIN(date) as start_date,
MAX(date) as end_date,
COUNT(*) as days_in_island
FROM date_ranges
GROUP BY grp
ORDER BY start_date;
SELECT
sale_date,
amount,
AVG(amount) OVER(
ORDER BY sale_date
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
) as rolling_avg
FROM daily_sales
ORDER BY sale_date;
List all employees with their department names, sorted by last name.
Show total salary for each department, ordered from highest to lowest.
Find employees earning more than $100,000.
List employees hired in the last 6 months, sorted by hire date.
Count employees in each department and show only those with more than 10 employees.
Show each employee with their manager's name (self join).
Compare each employee's salary to their department average.
Calculate years of service for each employee.
Rank employees by salary within their department using window functions.
Track position changes over time using self-joins and date ranges.
Build a complete organizational hierarchy using recursive CTEs.
Rewrite an inefficient query to improve performance by 10x.
Unlock all advanced features and tools