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
1
Find every pair of reservations for the same listing whose stay dates genuinely overlap — not reservations that simply share a listing, and not back-to-back turnovers where one checkout date equals the next check-in date. Treat a NULL check_out as an open-ended stay that hasn't ended yet (it overlaps with any later reservation on that listing). Return each overlapping pair once (not twice, and never a reservation paired with itself) as listing_id, guest_1, check_in_1, check_out_1, guest_2, check_in_2, check_out_2, sorted by listing_id then guest_1.
Self JOIN · COALESCE · JOIN
Airbnb mid
2
For each customer, calculate the total number of orders and total order amount per month. Treat any NULL order_amount as 0. Return customer_id, order_month (in YYYY-MM format), total_orders, and total_amount, sorted by customer_id and then order_month.
GROUP BY · strftime · COALESCE
Amazon easy
3
For each user in learning_activity, calculate total_xp as the sum of xp_earned (treating a NULL xp_earned, from a streak-freeze day, as 0). Calculate avg_xp_per_day as the average xp_earned across all logged days for that user, also treating NULL as 0 — a freeze day should pull the average down, not be excluded from it. Calculate language_count as the number of distinct languages the user has activity for, and languages_list as those distinct language names joined into a single comma-separated string, sorted alphabetically. Return user_name, total_xp, avg_xp_per_day (rounded to 2 decimal places), language_count, and languages_list, sorted by total_xp in descending order.
GROUP_CONCAT · COALESCE · COUNT(DISTINCT)
Duolingo mid
4
Find suppliers whose average product unit price is greater than the average unit price of all suppliers in the same category. Return the supplier name, category, and average unit price. Sort the results by category and then by average unit price in descending order.
JOIN · GROUP BY · AVG
Flipkart mid
5
For each reseller, calculate net revenue as the total value of delivered orders minus the total value of RTO (returned) orders. Only include resellers with at least 5 total orders. Rank resellers within their product category by net revenue, using DENSE_RANK so tied resellers share a rank. Also calculate the running total of net revenue within each category, ordered by rank (and by reseller name to break ties consistently). Return reseller_name, category, total_orders, net_revenue, category_rank, and running_net_revenue, sorted by category, then rank, then reseller name.
JOIN · CASE WHEN · GROUP BY
Meesho hard
6
Find products whose total sales quantity is greater than the average total sales quantity of products from the same brand. Return the product name, brand and total sales quantity. Sort the result by brand and total sales quantity in descending order.
JOIN · GROUP BY · SUM
Myntra mid
7
For each TV show, calculate the completion percentage based on users who started Episode 1 versus users who watched the final episode. Round the result to 2 decimal places.
JOIN · WHERE IN · GROUP BY
Netflix mid
8
The trips table sometimes has multiple rows for the same trip_id, logged because of app retries. For each trip_id, keep only the row with the most recent updated_at and discard the older duplicate rows. Return trip_id, driver_id, rider_id, fare, and updated_at for the deduplicated trips, sorted by trip_id.
ROW_NUMBER · PARTITION BY · OVER
Ola mid
9
For each age group, calculate the percentage of time spent sending snaps vs opening snaps out of total send+open time. Round to 2 decimal places.
JOIN · WHERE IN · GROUP BY
Snapchat mid
10
For each user and month in listening_stats, use LAG() to find that same user's previous month minutes_streamed (ordered by month). Treat a NULL minutes_streamed as 0 when comparing. Flag a row as churn_risk = 1 if minutes dropped by more than 50% compared to the previous month, otherwise churn_risk = 0. A user's first month in the data has no previous month to compare against, so churn_risk should be 0 for that row. Return user_name, month, minutes_streamed, previous_month_minutes, and churn_risk, sorted by user_name and month.
LAG · PARTITION BY · COALESCE
Spotify mid