Foodly
Food delivery
Foodly is a food delivery platform operating in five Indian cities. Customers order from partner restaurants in the app and delivery partners pick up and deliver the food. The business cares about restaurant performance, customer retention, delivery speed and payment reliability. As a Foodly analyst you work with orders, line items, deliveries, payments and reviews, the same mix you meet in SQL rounds at food-tech and quick-commerce companies.
See the Foodly tables
Foodly schema
All tables live in the foodly schema, so write foodly.customers in your queries.
foodly.customers
One row per customer.
customer_id(INT) — PKfirst_name(VARCHAR(50))last_name(VARCHAR(50))email(VARCHAR(120))phone(VARCHAR(15))signup_date(DATE)city(VARCHAR(40))marketing_opt_in(BOOLEAN)
foodly.customer_addresses
Saved delivery addresses.
address_id(INT) — PKcustomer_id(INT) — FK → customers.customer_idaddress_line1(VARCHAR(120))address_line2(VARCHAR(120)) — nullablecity(VARCHAR(40))state(VARCHAR(40))postal_code(VARCHAR(10))is_default(BOOLEAN)created_at(TIMESTAMP)
foodly.restaurants
Partner restaurants.
restaurant_id(INT) — PKname(VARCHAR(80))city(VARCHAR(40))cuisine_type(VARCHAR(30))rating(DECIMAL(2,1)) — displayed rating on the app, 1 to 5onboarded_at(TIMESTAMP)is_active(BOOLEAN)
foodly.menu_items
Dishes on each restaurant's menu.
menu_item_id(INT) — PKrestaurant_id(INT) — FK → restaurants.restaurant_iditem_name(VARCHAR(80))category(VARCHAR(30)) — 'starter', 'main', 'dessert', 'beverage'price(DECIMAL(8,2)) — current menu priceis_available(BOOLEAN)created_at(TIMESTAMP)
foodly.orders
One row per order.
order_id(INT) — PKcustomer_id(INT) — FK → customers.customer_idrestaurant_id(INT) — FK → restaurants.restaurant_idorder_time(TIMESTAMP)status(VARCHAR(20)) — 'placed', 'accepted', 'preparing', 'out_for_delivery', 'delivered', 'cancelled'total_amount(DECIMAL(10,2)) — charged to the customer: items + delivery_fee - discount_amountdelivery_fee(DECIMAL(8,2))discount_amount(DECIMAL(8,2)) — 0 when nonecity(VARCHAR(40)) — city the order was placed in
foodly.order_items
Dishes in each order.
order_item_id(INT) — PKorder_id(INT) — FK → orders.order_idmenu_item_id(INT) — FK → menu_items.menu_item_idquantity(INT)item_price(DECIMAL(8,2)) — unit price at the time of the order
foodly.delivery_partners
Riders who deliver orders.
delivery_partner_id(INT) — PKfull_name(VARCHAR(80))phone(VARCHAR(15))city(VARCHAR(40))rating(DECIMAL(2,1))is_active(BOOLEAN)onboarded_at(TIMESTAMP)
foodly.deliveries
Delivery assignments. An order can have a cancelled assignment before the one that delivered it.
delivery_id(INT) — PKorder_id(INT) — FK → orders.order_iddelivery_partner_id(INT) — FK → delivery_partners.delivery_partner_idpickup_time(TIMESTAMP) — nullabledropoff_time(TIMESTAMP) — nullabledistance_km(DECIMAL(5,1))status(VARCHAR(25)) — 'assigned', 'picked_up', 'delivered', 'cancelled_by_partner'cancelled_reason(VARCHAR(80)) — nullable
foodly.payments
Payment attempts for orders.
payment_id(INT) — PKorder_id(INT) — FK → orders.order_idamount(DECIMAL(10,2))payment_method(VARCHAR(20)) — 'card', 'upi', 'wallet', 'cod'payment_status(VARCHAR(20)) — 'success', 'failed', 'refunded'created_at(TIMESTAMP)
foodly.restaurant_reviews
Customer reviews of restaurants.
review_id(INT) — PKcustomer_id(INT) — FK → customers.customer_idrestaurant_id(INT) — FK → restaurants.restaurant_idrating(INT) — 1 to 5review_text(TEXT) — nullablecreated_at(TIMESTAMP)is_verified_purchase(BOOLEAN)
Beginner (12)
- BeginnerThe first 20 customersOpen now
- BeginnerCustomer citiesOpen now
- BeginnerCustomers and marketing opt-in
- BeginnerActive restaurants in Bengaluru
- BeginnerDelivered orders for one customer
- BeginnerOrders with a discount
- BeginnerAverage restaurant rating
- BeginnerMenu size per restaurant
- BeginnerDeliveries by status
- BeginnerFailed payments
- BeginnerTop-rated delivery partners
- BeginnerAverage delivery distance
Intermediate (16)
- IntermediateGross and net revenue
- IntermediateRevenue by city
- IntermediateCustomers with more than 20 delivered orders
- IntermediateCustomers who ordered last calendar year
- IntermediateTop 10 restaurants by delivered orders
- IntermediateTop 10 dishes by quantity sold
- IntermediatePayment success rate by method
- IntermediateAverage delivery time
- IntermediateCustomers by order-frequency bucket
- IntermediateRestaurant review score (min 20 reviews)
- IntermediateDelivered orders whose payments don't add up
- IntermediateAverage order value per customer
- IntermediateOrders by hour of day
- IntermediateTop 5 cuisines by revenue
- IntermediatePreserve restaurants when filtering recent order joins
- IntermediatePivot delivered and cancelled orders by city
Advanced (21)
- AdvancedMonthly revenue and MoM growth
- Advanced7-day rolling delivered orders
- AdvancedRank customers by lifetime spend
- AdvancedHigh-revenue restaurants with poor reviews
- AdvancedCustomer RFM metrics
- AdvancedChurned customers (90 days)
- AdvancedSecond order within 30 days
- AdvancedOn-time delivery rate by city
- AdvancedDelivery partner leaderboard
- AdvancedRestaurant onboarding to first order
- AdvancedSignup-cohort week-one ordering retention
- AdvancedReconcile receipt totals with order lines and fees
- AdvancedBuild a JSON menu grouped by category
- AdvancedCustomers with at least three distinct ordered cuisines
- AdvancedLatest payment attempt without losing unpaid orders
- AdvancedDiscount comparison without claiming a causal A/B test
- AdvancedConservative email-shape audit
- AdvancedHistorical sold prices versus today's menu prices
- AdvancedCustomers who bought from both named restaurants
- AdvancedLongest gap between restaurant orders
- AdvancedUse a savepoint to undo one workflow step
Mock interview round (10)
- AdvancedMock round 1: 6-month revenue by city
- AdvancedMock round 2: Orders from new vs returning customers
- AdvancedMock round 3: Restaurants with high cancellation
- AdvancedMock round 4: Power users vs casual users
- AdvancedMock round 5: Restaurant KPI table
- AdvancedMock round 6: Payment reliability and refunds
- AdvancedMock round 7: Delivery partner churn
- AdvancedMock round 8: Dish contribution estimate
- AdvancedMock round 9: City growth vs churn
- AdvancedMock round 10: City operations summary