Easy. List Electronics products with their price. Target: 28 rows · product_id, product_name, price · (1, Headphones, 800); (2, Keyboard v2, 2230) …
SELECT product_id, product_name, price FROM products WHERE category = 'Electronics' ORDER BY product_id;
Easy. Show the 20 most recent delivered orders. Target: 20 rows · order_id, order_date, status · (835, 2025-12-29, delivered); (1955, 2025-12-28, delivered) …
SELECT order_id, order_date, status FROM orders WHERE status = 'delivered' ORDER BY order_date DESC, order_id DESC LIMIT 20;
Easy. List customers who live in Delhi. Target: 20 rows · customer_id, customer_name · (26, Kabir Gill); (27, Rahul Das) …
SELECT customer_id, customer_name FROM customers WHERE city = 'Delhi' ORDER BY customer_id LIMIT 20;
Easy. List sellers rated 4.5 or higher. Target: 14 rows · seller_id, seller_name, rating · (1, Traders Kaur, 4.99); (12, Store Mehta, 4.98) …
SELECT seller_id, seller_name, rating FROM sellers WHERE rating >= 4.5 ORDER BY rating DESC, seller_id;
Easy. List products that are out of stock. Target: 3 rows · product_id, product_name, stock · (2, Keyboard v2, 0); (9, Mug v3, 0) …
SELECT product_id, product_name, stock FROM products WHERE stock = 0 ORDER BY product_id LIMIT 20;
Easy. Show the first 20 orders paid by UPI. Target: 20 rows · order_id, order_date, payment_mode · (5, 2024-05-25, upi); (8, 2024-10-25, upi) …
SELECT order_id, order_date, payment_mode FROM orders WHERE payment_mode = 'upi' ORDER BY order_id LIMIT 20;
Easy. List products priced above 2,000. Target: 20 rows · product_id, product_name, price · (21, Marker set v2, 3000); (30, Design basics v3, 3000) …
SELECT product_id, product_name, price FROM products WHERE price > 2000 ORDER BY price DESC, product_id LIMIT 20;
Easy. List every product category once. Target: 6 rows · category · (Books); (Electronics) …
SELECT DISTINCT category FROM products ORDER BY category;
Easy. Count all orders. Target: 1 row · orders · (2000)
SELECT COUNT(*) AS orders FROM orders;
Easy. Show the line items of order 1. Target: 1 row · order_id, product_id, quantity, unit_price · (1, 135, 2, 1390)
SELECT order_id, product_id, quantity, unit_price FROM order_items WHERE order_id = 1 ORDER BY product_id;
Medium. List products priced between 500 and 1,500. Target: 20 rows · product_name, price · (Photo frame 137, 500); (Backpack 181, 500) …
SELECT product_name, price FROM products WHERE price BETWEEN 500 AND 1500 ORDER BY price, product_id LIMIT 20;
Medium. List cancelled and returned orders. Target: 20 rows · order_id, status, order_date · (1, returned, 2025-10-14); (7, cancelled, 2025-07-29) …
SELECT order_id, status, order_date FROM orders WHERE status IN ('cancelled', 'returned') ORDER BY order_id LIMIT 20;Medium. List customers whose name starts with K. Target: 20 rows · customer_id, customer_name · (25, Kabir Sharma); (26, Kabir Gill) …
SELECT customer_id, customer_name FROM customers WHERE customer_name LIKE 'K%' ORDER BY customer_id LIMIT 20;
Medium. List orders placed in the first quarter of 2025. Target: 20 rows · order_id, order_date · (311, 2025-01-01); (417, 2025-01-02) …
SELECT order_id, order_date FROM orders WHERE order_date >= '2025-01-01' AND order_date < '2025-04-01' ORDER BY order_date, order_id LIMIT 20;
Medium. Show the payable amount for the first 20 order lines. Target: 20 rows · order_id, product_id, payable · (1, 135, 2529.8); (2, 5, 1981.2) …
SELECT order_id, product_id, ROUND(quantity * unit_price * (100 - discount) / 100, 2) AS payable FROM order_items ORDER BY order_id, product_id LIMIT 20;
Medium. Label every order with a fulfilment stage. Target: 20 rows · order_id, status, stage · (1, returned, Needs review); (2, delivered, Closed) …
SELECT order_id, status, CASE WHEN status = 'delivered' THEN 'Closed' WHEN status = 'shipped' THEN 'In transit' ELSE 'Needs review' END AS stage FROM orders ORDER BY order_id LIMIT 20;
Medium. Show product names in capitals with their category. Target: 20 rows · product, category · (HEADPHONES, Electronics); (KEYBOARD V2, Electronics) …
SELECT UPPER(product_name) AS product, category FROM products ORDER BY product_id LIMIT 20;
Medium. Label each seller by rating band. Target: 20 rows · seller_id, seller_name, rating, band · (1, Traders Kaur, 4.99, Top); (12, Store Mehta, 4.98, Top) …
SELECT seller_id, seller_name, rating, CASE WHEN rating >= 4.5 THEN 'Top' WHEN rating >= 4 THEN 'Good' ELSE 'Watch' END AS band FROM sellers ORDER BY rating DESC, seller_id LIMIT 20;
Medium. List customers who signed up in 2025. Target: 20 rows · customer_id, customer_name, signup_date · (2, Tanvi Nair, 2025-03-09); (3, Harpreet Khan, 2025-03-03) …
SELECT customer_id, customer_name, signup_date FROM customers WHERE signup_date >= '2025-01-01' AND signup_date < '2026-01-01' ORDER BY customer_id LIMIT 20;
Medium. Count how many different cities customers come from. Target: 1 row · cities · (10)
SELECT COUNT(DISTINCT city) AS cities FROM customers;
Medium. Show each product name and its character length. Target: 20 rows · product_name, name_length · (Headphones, 10); (Keyboard v2, 11) …
SELECT product_name, LENGTH(product_name) AS name_length FROM products ORDER BY product_id LIMIT 20;
Medium. List cash-on-delivery orders in 2024. Target: 20 rows · order_id, order_date · (4, 2024-09-17); (11, 2024-02-08) …
SELECT order_id, order_date FROM orders WHERE payment_mode = 'cod' AND order_date >= '2024-01-01' AND order_date < '2025-01-01' ORDER BY order_id LIMIT 20;
Hard. Count orders by status. Target: 4 rows · status, orders · (delivered, 1548); (shipped, 201) …
SELECT status, COUNT(*) AS orders FROM orders GROUP BY status ORDER BY orders DESC, status;
Hard. Show delivered revenue per category. Target: 6 rows · category, revenue · (Stationery, 2502814); (Fashion, 2477187.3) …
SELECT p.category, SUM(ROUND(i.quantity * i.unit_price * (100 - i.discount) / 100, 2)) AS revenue FROM order_items i JOIN orders o ON o.order_id = i.order_id JOIN products p ON p.product_id = i.product_id WHERE o.status = 'delivered' GROUP BY p.category ORDER BY revenue DESC, p.category;
Hard. Show the average product price per category. Target: 6 rows · category, avg_price · (Home, 1711.39); (Fashion, 1576.1) …
SELECT category, ROUND(AVG(price), 2) AS avg_price FROM products GROUP BY category ORDER BY avg_price DESC, category;
Hard. List customers with more than 5 orders. Target: 20 rows · customer_id, customer_name, orders · (1, Gurleen Bose, 28); (2, Tanvi Nair, 18) …
SELECT c.customer_id, c.customer_name, COUNT(*) AS orders FROM customers c JOIN orders o ON o.customer_id = c.customer_id GROUP BY c.customer_id, c.customer_name HAVING COUNT(*) > 5 ORDER BY orders DESC, c.customer_id LIMIT 20;
Hard. List sellers who list more than 3 products. Target: 20 rows · seller_id, seller_name, products · (7, Traders Gill, 9); (17, Store Rao, 8) …
SELECT s.seller_id, s.seller_name, COUNT(*) AS products FROM sellers s JOIN products p ON p.seller_id = s.seller_id GROUP BY s.seller_id, s.seller_name HAVING COUNT(*) > 3 ORDER BY products DESC, s.seller_id LIMIT 20;
Hard. Show delivered revenue per month of 2025. Target: 12 rows · month, revenue · (2025-01, 499711.8); (2025-02, 462268.2) …
SELECT DATE_FORMAT(o.order_date, '%Y-%m') AS month, SUM(ROUND(i.quantity * i.unit_price * (100 - i.discount) / 100, 2)) AS revenue FROM order_items i JOIN orders o ON o.order_id = i.order_id WHERE o.status = 'delivered' AND o.order_date >= '2025-01-01' AND o.order_date < '2026-01-01' GROUP BY month ORDER BY month;
Hard. Show categories that list more than 25 products. Target: 5 rows · category, products · (Fashion, 41); (Stationery, 40) …
SELECT category, COUNT(*) AS products FROM products GROUP BY category HAVING COUNT(*) > 25 ORDER BY products DESC, category;
Hard. Show the 5 products that sold the most units in delivered orders. Target: 5 rows · product_id, product_name, units · (17, Notebook, 83); (49, Water bottle 49, 82) …
SELECT p.product_id, p.product_name, SUM(i.quantity) AS units FROM order_items i JOIN orders o ON o.order_id = i.order_id JOIN products p ON p.product_id = i.product_id WHERE o.status = 'delivered' GROUP BY p.product_id, p.product_name ORDER BY units DESC, p.product_id LIMIT 5;
Hard. List sellers whose average product price is above 1,500. Target: 24 rows · seller_id, seller_name, avg_price · (26, Mart Nair, 2555); (48, Mart Reddy, 2490) …
SELECT s.seller_id, s.seller_name, ROUND(AVG(p.price), 2) AS avg_price FROM sellers s JOIN products p ON p.seller_id = s.seller_id GROUP BY s.seller_id, s.seller_name HAVING AVG(p.price) > 1500 ORDER BY avg_price DESC, s.seller_id;
Hard. Show the average delivered order value per payment mode. Target: 4 rows · payment_mode, avg_order_value · (netbanking, 8068.74); (upi, 8030.89) …
WITH per_order AS (SELECT o.order_id, o.payment_mode, SUM(ROUND(i.quantity * i.unit_price * (100 - i.discount) / 100, 2)) AS order_value FROM order_items i JOIN orders o ON o.order_id = i.order_id WHERE o.status = 'delivered' GROUP BY o.order_id, o.payment_mode) SELECT payment_mode, ROUND(AVG(order_value), 2) AS avg_order_value FROM per_order GROUP BY payment_mode ORDER BY avg_order_value DESC, payment_mode;
Hard. Show the return rate per category, highest first. Target: 6 rows · category, return_pct · (Electronics, 5.2); (Fashion, 5) …
SELECT p.category, ROUND(100 * SUM(CASE WHEN o.status = 'returned' THEN 1 ELSE 0 END) / COUNT(*), 1) AS return_pct FROM order_items i JOIN orders o ON o.order_id = i.order_id JOIN products p ON p.product_id = i.product_id WHERE o.status IN ('delivered', 'returned') GROUP BY p.category ORDER BY return_pct DESC, p.category;Hard. List orders with more than 2 line items. Target: 20 rows · order_id, lines · (5, 3); (8, 3) …
SELECT order_id, COUNT(*) AS lines FROM order_items GROUP BY order_id HAVING COUNT(*) > 2 ORDER BY lines DESC, order_id LIMIT 20;
Hard. List products that have never been ordered. Target: 0 rows · product_id, product_name ·
SELECT p.product_id, p.product_name FROM products p WHERE NOT EXISTS (SELECT 1 FROM order_items i WHERE i.product_id = p.product_id) ORDER BY p.product_id LIMIT 20;
Hard. Show cities with more than 150 customers. Target: 0 rows · city, customers ·
SELECT city, COUNT(*) AS customers FROM customers GROUP BY city HAVING COUNT(*) > 150 ORDER BY customers DESC, city;
Professional. Show the 10 customers with the highest delivered spend. Target: 10 rows · customer_id, customer_name, spend · (12, Pooja Verma, 117648.3); (1, Gurleen Bose, 108337.8) …
SELECT c.customer_id, c.customer_name, SUM(ROUND(i.quantity * i.unit_price * (100 - i.discount) / 100, 2)) AS spend FROM order_items i JOIN orders o ON o.order_id = i.order_id JOIN customers c ON c.customer_id = o.customer_id WHERE o.status = 'delivered' GROUP BY c.customer_id, c.customer_name ORDER BY spend DESC, c.customer_id LIMIT 10;
Professional. Show each category's share of delivered revenue. Target: 6 rows · category, revenue, pct · (Stationery, 2502814, 20.4); (Fashion, 2477187.3, 20.2) …
SELECT p.category, SUM(ROUND(i.quantity * i.unit_price * (100 - i.discount) / 100, 2)) AS revenue, ROUND(100 * SUM(ROUND(i.quantity * i.unit_price * (100 - i.discount) / 100, 2)) / (SELECT SUM(ROUND(i.quantity * i.unit_price * (100 - i.discount) / 100, 2)) FROM order_items i JOIN orders o ON o.order_id = i.order_id WHERE o.status = 'delivered'), 1) AS pct FROM order_items i JOIN orders o ON o.order_id = i.order_id JOIN products p ON p.product_id = i.product_id WHERE o.status = 'delivered' GROUP BY p.category ORDER BY revenue DESC, p.category;
Professional. Rank products by delivered revenue inside their category. Target: 20 rows · category, product_name, revenue, rnk · (Books, Design basics 54, 146191.5, 1); (Books, Data stories, 140389.4, 2) …
WITH r AS (SELECT p.category, p.product_name, SUM(ROUND(i.quantity * i.unit_price * (100 - i.discount) / 100, 2)) AS revenue, RANK() OVER (PARTITION BY p.category ORDER BY SUM(ROUND(i.quantity * i.unit_price * (100 - i.discount) / 100, 2)) DESC) AS rnk FROM order_items i JOIN orders o ON o.order_id = i.order_id JOIN products p ON p.product_id = i.product_id WHERE o.status = 'delivered' GROUP BY p.category, p.product_id, p.product_name) SELECT category, product_name, revenue, rnk FROM r ORDER BY category, rnk LIMIT 20;
Professional. Show 2025 delivered revenue by month with a running total. Target: 12 rows · month, revenue, running_total · (2025-01, 499711.8, 499711.8); (2025-02, 462268.2, 961980) …
WITH m AS (SELECT DATE_FORMAT(o.order_date, '%Y-%m') AS month, SUM(ROUND(i.quantity * i.unit_price * (100 - i.discount) / 100, 2)) AS revenue FROM order_items i JOIN orders o ON o.order_id = i.order_id WHERE o.status = 'delivered' AND o.order_date >= '2025-01-01' AND o.order_date < '2026-01-01' GROUP BY month) SELECT month, revenue, SUM(revenue) OVER (ORDER BY month) AS running_total FROM m ORDER BY month;
Professional. Show the month-over-month change in delivered orders for 2025. Target: 12 rows · month, orders, prev_orders, change · (2025-01, 68, NULL, NULL); (2025-02, 59, 68, -9) …
WITH m AS (SELECT DATE_FORMAT(order_date, '%Y-%m') AS month, COUNT(*) AS orders FROM orders WHERE status = 'delivered' AND order_date >= '2025-01-01' AND order_date < '2026-01-01' GROUP BY month) SELECT month, orders, LAG(orders) OVER (ORDER BY month) AS prev_orders, orders - LAG(orders) OVER (ORDER BY month) AS change FROM m ORDER BY month;
Professional. List customers with 3 or more delivered orders. Target: 20 rows · customer_id, customer_name, delivered_orders · (1, Gurleen Bose, 18); (3, Harpreet Khan, 14) …
SELECT c.customer_id, c.customer_name, COUNT(*) AS delivered_orders FROM customers c JOIN orders o ON o.customer_id = c.customer_id WHERE o.status = 'delivered' GROUP BY c.customer_id, c.customer_name HAVING COUNT(*) >= 3 ORDER BY delivered_orders DESC, c.customer_id LIMIT 20;
Professional. Show the best-selling product in each category by units. Target: 6 rows · category, product_name, units · (Books, Design basics 54, 71); (Electronics, Power bank 57, 82) …
WITH r AS (SELECT p.category, p.product_name, SUM(i.quantity) AS units, ROW_NUMBER() OVER (PARTITION BY p.category ORDER BY SUM(i.quantity) DESC, p.product_id) AS rn FROM order_items i JOIN orders o ON o.order_id = i.order_id JOIN products p ON p.product_id = i.product_id WHERE o.status = 'delivered' GROUP BY p.category, p.product_id, p.product_name) SELECT category, product_name, units FROM r WHERE rn = 1 ORDER BY category;
Professional. List customers who have never placed an order. Target: 14 rows · customer_id, customer_name · (66, Anaya Kaur); (149, Meera Sharma) …
SELECT c.customer_id, c.customer_name FROM customers c WHERE NOT EXISTS (SELECT 1 FROM orders o WHERE o.customer_id = c.customer_id) ORDER BY c.customer_id LIMIT 20;
Professional. List products priced above their category's average. Target: 20 rows · product_name, category, price · (Design basics v3, Books, 3000); (Python primer 163, Books, 2900) …
SELECT p.product_name, p.category, p.price FROM products p WHERE p.price > (SELECT AVG(x.price) FROM products x WHERE x.category = p.category) ORDER BY p.category, p.price DESC, p.product_id LIMIT 20;
Professional. Show the 10 sellers with the most delivered revenue. Target: 10 rows · seller_id, seller_name, revenue · (25, Store Sharma, 728459.4); (45, Bazaar Reddy, 635834.7) …
SELECT s.seller_id, s.seller_name, SUM(ROUND(i.quantity * i.unit_price * (100 - i.discount) / 100, 2)) AS revenue FROM order_items i JOIN orders o ON o.order_id = i.order_id JOIN products p ON p.product_id = i.product_id JOIN sellers s ON s.seller_id = p.seller_id WHERE o.status = 'delivered' GROUP BY s.seller_id, s.seller_name ORDER BY revenue DESC, s.seller_id LIMIT 10;
Professional. Show each customer's first order date. Target: 20 rows · customer_id, customer_name, first_order · (298, Vihaan Verma, 2025-12-26); (498, Ishaan Chopra, 2025-12-19) …
SELECT c.customer_id, c.customer_name, MIN(o.order_date) AS first_order FROM customers c JOIN orders o ON o.customer_id = c.customer_id GROUP BY c.customer_id, c.customer_name ORDER BY first_order DESC, c.customer_id LIMIT 20;
Professional. Build a 2025 monthly dashboard: delivered orders, revenue and average order value. Target: 12 rows · month, orders, revenue, avg_order_value · (2025-01, 68, 499711.8, 7348.7); (2025-02, 59, 462268.2, 7835.05) …
WITH per_order AS (SELECT o.order_id, DATE_FORMAT(o.order_date, '%Y-%m') AS month, SUM(ROUND(i.quantity * i.unit_price * (100 - i.discount) / 100, 2)) AS order_value FROM order_items i JOIN orders o ON o.order_id = i.order_id WHERE o.status = 'delivered' AND o.order_date >= '2025-01-01' AND o.order_date < '2026-01-01' GROUP BY o.order_id, month) SELECT month, COUNT(*) AS orders, SUM(order_value) AS revenue, ROUND(AVG(order_value), 2) AS avg_order_value FROM per_order GROUP BY month ORDER BY month;
Professional. Show each payment mode's share of delivered revenue in 2025. Target: 4 rows · payment_mode, revenue, pct · (card, 1786860.8, 29); (netbanking, 1487571, 24.2) …
SELECT o.payment_mode, SUM(ROUND(i.quantity * i.unit_price * (100 - i.discount) / 100, 2)) AS revenue, ROUND(100 * SUM(ROUND(i.quantity * i.unit_price * (100 - i.discount) / 100, 2)) / (SELECT SUM(ROUND(i.quantity * i.unit_price * (100 - i.discount) / 100, 2)) FROM order_items i JOIN orders o2 ON o2.order_id = i.order_id WHERE o2.status = 'delivered' AND o2.order_date >= '2025-01-01' AND o2.order_date < '2026-01-01'), 1) AS pct FROM order_items i JOIN orders o ON o.order_id = i.order_id WHERE o.status = 'delivered' AND o.order_date >= '2025-01-01' AND o.order_date < '2026-01-01' GROUP BY o.payment_mode ORDER BY revenue DESC, o.payment_mode;
Professional. Show each seller's best-selling product by delivered units. Target: 20 rows · seller_name, product_name, units · (Bazaar Gill, Notebook, 83); (Shop Mehta, Water bottle 49, 82) …
WITH r AS (SELECT s.seller_name, p.product_name, SUM(i.quantity) AS units, ROW_NUMBER() OVER (PARTITION BY s.seller_id ORDER BY SUM(i.quantity) DESC, p.product_id) AS rn FROM order_items i JOIN orders o ON o.order_id = i.order_id JOIN products p ON p.product_id = i.product_id JOIN sellers s ON s.seller_id = p.seller_id WHERE o.status = 'delivered' GROUP BY s.seller_id, s.seller_name, p.product_id, p.product_name) SELECT seller_name, product_name, units FROM r WHERE rn = 1 ORDER BY units DESC, seller_name LIMIT 20;