Free · In-browser · No signup

Practice SQL with
real company scenarios.

Click any question below, write SQL, run it live in your browser, and understand every concept in your language.

10 questions
⚠️ Note: These questions may or may not have been asked at the companies shown — the goal is to teach SQL through real-world usecases.
# Question Company Difficulty
21
Using a subquery in the FROM clause, first compute for each kitchen_name in swiggy_kitchen_orders: cancelled_count (orders with order_status = 'cancelled'), total_resolved (orders where order_status is not NULL), and cancellation_rate as cancelled_count divided by total_resolved times 100, rounded to 2 decimal places. Then, in the outer query, return only the kitchens where cancellation_rate is greater than 20, with columns kitchen_name, cancelled_count, total_resolved, and cancellation_rate, sorted by cancellation_rate in descending order.
Derived Table · Subquery in FROM · CASE WHEN
Swiggy hard
22
For each employee, display their name, department, latest performance rating, the previous performance rating (to track improvement), their ranking within the department, and whether their latest rating is above or below their department's average. Sort by department and ranking.
Window Functions · ROW_NUMBER · RANK
Techcorp mid
23
For each user, count the total number of likes they have sent to others. Show user name along with the count, sorted by count in descending order.
JOIN · GROUP BY · COUNT
Tinder easy
24
For each rider, calculate the total number of trips they've taken and their average fare per trip. Treat any trip with a missing (NULL) fare_amount as 0 when calculating the average, rather than excluding it. Return rider_name, total_trips, and avg_fare (rounded to 2 decimal places), sorted by avg_fare in descending order.
JOIN · GROUP BY · COUNT
Uber easy
25
Find total earnings of each driver and show top 3 earning drivers per city.
JOIN · GROUP BY · SUM
Uber mid
26
For each student in mock_test_scores who has a non-NULL score, calculate their percentile as PERCENT_RANK() expressed as a percentage (0 to 100, rounded to 2 decimal places) such that the highest-scoring student ends up with a percentile near 100 and the lowest-scoring student ends up near 0 — matching how 'percentile' is normally understood ('I scored better than X% of test-takers'). Exclude Vikram, whose score is NULL, entirely. Return student_name, score, and percentile, sorted by score descending.
PERCENT_RANK · Window Functions · RANK
Unacademy mid
27
For each video, calculate the percentage of viewers who watched until the end out of all viewers who started the video. Round the result to 2 decimal places.
JOIN · WHERE · GROUP BY
Youtube mid
28
For each store in zepto_daily_sales, excluding any row where revenue is NULL (the store was closed, not a zero-revenue day), compute a 3-day moving average of revenue ordered by sale_date — the average of the current trading day and the two trading days immediately before it (fewer days if not enough history exists yet). Return store_name, sale_date, revenue, and moving_avg_3day rounded to 2 decimal places, sorted by store_name and sale_date.
ROWS BETWEEN · Window Functions · PARTITION BY
Zepto hard
29
For each account in zerodha_clients where account_type is 'corporate', return client_name and email for accounts that either use a personal email domain (gmail.com, yahoo.com, or hotmail.com) or have no email on file at all. Sort by client_name.
LIKE · WHERE · IS NULL
Zerodha mid
30
Find every restaurant that has never had a cancelled order — meaning it has zero orders with status = 'cancelled'. This includes restaurants with no orders at all, since they trivially satisfy 'never cancelled.' Use EXISTS or NOT EXISTS with a correlated subquery rather than aggregating and filtering afterward. Return restaurant_name and city, sorted alphabetically by restaurant_name.
EXISTS · NOT EXISTS · Correlated Subquery
Zomato mid