LEARN · SQL · ADVANCED PRACTICE
50 Advanced SQL Interview Questions
Recursive CTEs and graph problems, concurrency and locking, enterprise analytics, ETL and data warehousing, and distributed-systems patterns like the transactional outbox. Senior developer, data engineer, and backend interview territory.
SQL dialect: PostgreSQL 15+.Unlike the rest of this course, this set doesn't show six-way dialect coverage, several of these techniques (SKIP LOCKED, ON CONFLICT, triggers, IS DISTINCT FROM, materialized views) are genuinely PostgreSQL-specific or don't translate cleanly to every engine. Each question is a reference problem with a scenario, a full solution, and an explanation, not something to run against a shared sample dataset.
0 / 50 reviewed
These are reference-style problems, not a shared dataset to query, "reviewed" is self-reported, marking that you've worked through a question, not an auto-graded score. Saved only in this browser.
Section 1 · DSA-Based SQL Challenges
Q1–10Recursive CTEs, graph traversal, interval merging, sequence detection, and one educational dynamic-programming formulation.
Complete Employee Reporting Hierarchy
Recursive CTE · HardAn enterprise with thousands of employees across multiple management levels. HR wants every employee reporting directly or indirectly to a particular manager, with their depth in the hierarchy.
EmployeeHierarchy(employee_id, employee_name, manager_id)
All Possible Paths Between Two Locations
Graph Algorithms · HardA logistics company maintains routes between warehouses and wants every possible path between two locations, without revisiting a location.
Routes(source, destination, distance)
Merge Overlapping Employee Leave Intervals
Interval Algorithms · HardAn HR system stores leave requests that can overlap or sit back-to-back, and needs them combined into continuous leave periods per employee.
EmployeeLeaves(employee_id, start_date, end_date)
Find Missing Invoice Numbers
Sequence Algorithms · HardA financial application generates sequential invoice numbers, and the finance team needs every missing number for an audit.
Invoices(invoice_number)
Median Salary Per Department
Statistical SQL · HardComparing median salary across departments instead of relying only on the average, which a handful of outlier salaries can skew.
Employees(employee_id, department_id, salary)
Longest Continuous Server Uptime
Gaps and Islands · HardA cloud company logs daily server status, and operations wants the single longest unbroken UP streak per server.
ServerStatus(server_id, status_date, status)
Group User Events Into Sessions
Event Processing · HardA platform treats user activity as one session until the user is inactive for more than 30 minutes.
UserEvents(user_id, event_time)
Maximum Sum of Three Consecutive Transactions
Sliding Window · HardA banking analytics system wants the largest combined value of any three consecutive transactions, per account.
AccountTransactions(account_id, transaction_id, transaction_time, amount)
Minimum Coins for a Target Amount
Dynamic Programming · HardA payment system wants the fewest coins, from a set of available denominations, that sum to a target amount.
CoinDenominations(denomination) — example: 1, 3, 4. Target: 6.
Consecutive Salary Sequences
Sequence Analysis · HardHR wants continuous integer salary bands actually represented by real employee salaries, with at least three distinct values in a row.
Employees(employee_id, salary)
Section 2 · Advanced Database System Design & Concurrency
Q11–20How SQL actually behaves under simultaneous requests: atomic updates, locking, idempotency, pagination at scale, and audit triggers.
Prevent Overselling the Last Item in Stock
Transaction Management · HardAn e-commerce platform has one laptop left, and two customers try to buy it at the same instant.
Inventory(product_id, available_quantity)
Safe Bank-to-Bank Transfer
ACID Transactions · HardMoving ₹10,000 from account 101 to account 102, without ever leaving a negative balance or a half-finished transfer.
Accounts(account_id, balance)
Concurrent Job Queue
Concurrent Processing · Hard20 background workers each need to independently claim one pending job, without two workers ever picking the same one.
Jobs(job_id, job_status, created_at, worker_id)
Sliding-Window API Rate Limiter
Backend System Design · HardA SaaS API allows at most 100 requests per user in any rolling 60-second window, and needs to find who's over the limit.
ApiRequests(request_id, user_id, request_time)
Optimistic Locking to Prevent Lost Updates
Concurrency Control · HardTwo admins open the same customer profile and both edit it. One save should never silently overwrite the other's unseen changes.
CustomerProfiles(customer_id, customer_name, email, version)
Detect Overlapping Room Reservations
Scheduling System · HardA hotel booking system needs to catch two reservations for the same room that overlap in time.
RoomBookings(booking_id, room_id, check_in, check_out)
Idempotent Payment Requests
Distributed Transaction Design · HardA payment gateway receives the same payment request more than once, because a client retried after a network timeout.
Payments(payment_id, idempotency_key, customer_id, amount, payment_status)
Find Changed Records Between Two Snapshots
Data Auditing · HardDaily customer snapshots are kept, and the team needs to know exactly which records actually changed between yesterday's and today's.
CustomerSnapshotOld(customer_id, customer_name, email, city), CustomerSnapshotNew(same columns)
Keyset Pagination at 100 Million Rows
Query Optimization · HardAn orders table with 100 million rows, where OFFSET-based pagination gets slower and slower on deeper pages.
Orders(order_id, customer_id, order_date, total_amount)
Automatic Salary Change Audit Trail
Database Architecture · HardEvery salary change must be logged, for compliance, without relying on every caller remembering to write the audit row themselves.
Employees(employee_id, salary), SalaryAudit(audit_id, employee_id, old_salary, new_salary, changed_at)
Section 3 · Real-World Corporate SQL Case Studies
Q21–35E-commerce, SaaS, fintech, and HR analytics problems built on CTEs, window functions, and correlated subqueries.
Identify Abandoned Shopping Carts
E-commerce · HardFind carts holding products that never turned into an order within 24 hours of being added.
CartItems(cart_id, customer_id, product_id, added_at), Orders(order_id, customer_id, order_date)
Monthly Customer Retention Cohorts
SaaS Analytics · HardWhat percentage of customers acquired in a given month are still active in later months.
CustomerActivity(customer_id, activity_date)
RFM Customer Segmentation
Marketing Analytics · HardClassifying customers by Recency, Frequency, and Monetary value, the standard marketing-analytics segmentation model.
Orders(customer_id, order_date, total_amount)
Expired Subscriptions With No Renewal
SaaS Billing · HardFind subscriptions marked ACTIVE whose end_date has already passed, with no follow-up subscription covering the gap.
Subscriptions(subscription_id, customer_id, start_date, end_date, status)
Net Revenue After Refunds
Financial Analytics · HardRevenue reporting that actually nets out successful refunds against successful payments, per order.
Payments(payment_id, order_id, amount, status), Refunds(refund_id, order_id, refund_amount, status)
Unusual Salary Increases
HR Analytics · HardFlagging any salary change greater than 30% over the employee's own previous recorded salary, for internal review.
SalaryHistory(employee_id, effective_date, salary)
Customers Who Bought From Every Category
Relational Division · HardFind customers who have purchased at least one product from every single product category that exists, not just several.
Customers, Orders, OrderItems, Products(product_id, category)
Orders Spanning Three or More Categories
E-commerce Analytics · HardA simpler, single-order version of the previous question: find orders whose items span at least three different categories.
Orders, OrderItems, Products(product_id, category)
First and Last Transaction Per Customer, Per Month
Financial Reporting · HardFor every customer and every month they transacted, find both their very first and very last transaction.
Transactions(customer_id, transaction_id, transaction_time, amount)
Three Consecutive Failed Payments
Payment Risk · HardDetect customers with three failed payment attempts in a row, a common early-warning signal for payment risk.
PaymentAttempts(attempt_id, customer_id, attempt_time, status)
Warehouse Products Needing Replenishment
Supply Chain · HardFind products whose actually-usable stock (available minus already-reserved) has dropped below its reorder threshold.
WarehouseInventory(warehouse_id, product_id, available_stock, reserved_stock, reorder_level)
Average Support Ticket Resolution Time
Customer Support Analytics · HardHow long tickets actually take to resolve, broken down by priority level.
SupportTickets(ticket_id, customer_id, created_at, resolved_at, priority)
Tickets That Violated Their SLA
SLA Monitoring · HardDifferent priority levels have different resolution-time targets (Critical: 2h, High: 8h, Medium: 24h, Low: 72h); find every ticket that blew past its own.
SupportTickets(ticket_id, priority, created_at, resolved_at)
Products With Three Months of Declining Revenue
Business Intelligence · HardFind products whose monthly revenue has dropped for three consecutive calendar months in a row, a genuine early-warning signal.
Orders, OrderItems(order_id, product_id, quantity, unit_price)
Customers Active in 5+ Months of the Last Year
Customer Analytics · HardIdentify genuinely engaged customers: ones who bought something in at least five different calendar months over the last year.
Orders(customer_id, order_date, status, total_amount)
Section 4 · Data Engineering, ETL & Large-Scale Challenges
Q36–43Deduplication, SCD Type 2, incremental loads, reconciliation, materialized views, and event-time processing.
Remove Duplicates, Keep the Latest Record
Data Cleaning · HardCustomer data imported from multiple systems has duplicates; keep only the most recently updated version of each.
CustomerImport(record_id, customer_id, customer_name, email, updated_at)
Slowly Changing Dimension Type 2
Data Warehouse Design · HardA data warehouse must keep a customer's full address history, not overwrite it, when a customer moves.
DimCustomer(customer_id, city, valid_from, valid_to, is_current)
Incremental ETL Load
ETL Pipeline · HardA source table has millions of rows; load only records modified since the last successful run, inserting new ones and updating changed ones.
SourceCustomers(customer_id, customer_name, email, updated_at), TargetCustomers(same columns)
Reconcile Source and Target After Migration
Data Reconciliation · HardAfter migrating transactions between two databases, find exactly what's missing or mismatched.
SourceTransactions(transaction_id, amount, status), TargetTransactions(same columns)
Pre-Aggregate Revenue With a Materialized View
Performance Engineering · HardA reporting dashboard recomputes the same customer-revenue aggregation from hundreds of millions of orders, on every single page load.
Orders(customer_id, total_amount, status, order_date)
Detect Out-of-Order Events
Event Streaming · HardPackage tracking events from multiple devices can arrive at the server in a different order than they actually happened.
TrackingEvents(package_id, event_id, event_time, received_at)
Daily Spending Limit Violations
Fintech Risk Management · HardA fintech platform caps successful daily spending at ₹50,000 per customer; find the transactions that pushed a customer over it.
Transactions(transaction_id, customer_id, transaction_time, amount, status)
Records Not Accessed in 180 Days
Database Maintenance · HardFind customer records nobody has touched in 180 days, candidates for archival.
CustomerAccessLog(customer_id, last_accessed_at)
Section 5 · Advanced System Design & Senior SQL Challenges
Q44–50Distributed-systems patterns expressed in SQL: outbox events, nth-highest without LIMIT, overlap detection, A/B tests, cycle detection, and multi-stage profitability.
Transactional Outbox Pattern
Distributed Architecture · HardCreating an order must also reliably publish an ORDER_CREATED event, but if the DB transaction succeeds and the message broker call fails separately, the event must not just vanish.
Orders(order_id, customer_id, total_amount), OutboxEvents(event_id, aggregate_id, event_type, payload, created_at, published_at)
Nth Highest Distinct Salary, Without LIMIT or TOP
Ranking Algorithms · HardA classic interview staple: find the 5th-highest distinct salary, without reaching for LIMIT/OFFSET or TOP at all.
Employees(employee_id, employee_name, salary)
Customers Inactive for Six Months
Customer Churn · HardPreviously active customers who haven't completed a purchase in the last six months, a standard churn-risk flag.
Orders(customer_id, order_date, status)
Detect Overlapping Employee Shifts
Scheduling · HardA hospital needs to catch any employee scheduled for two shifts that overlap in time.
EmployeeShifts(shift_id, employee_id, shift_start, shift_end)
A/B Test Conversion Rates
Experimentation · HardComparing two landing-page variants (A and B) by what fraction of exposed users actually converted.
ExperimentEvents(user_id, variant, event_type, event_time)
Detect Circular Task Dependencies
Graph Algorithms · HardA project management tool needs to catch task A depending on B depending on ... eventually depending back on A, before it causes a deadlock in actual task scheduling.
TaskDependencies(task_id, depends_on_task_id)
Customer Profitability After Discounts, Refunds, and Cost
Financial Modeling · HardRank customers by actual profit, not revenue: gross sales minus discounts, minus refunds, minus the cost of goods sold.
Orders(order_id, customer_id, discount_amount, status), OrderItems(order_id, product_id, quantity, unit_price), Products(product_id, cost_price), Refunds(order_id, refund_amount, status)
Run These for Real
These target PostgreSQL 15+ specifically, so DB Fiddle (which actually runs PostgreSQL, unlike MySQL/SQL Server-oriented playgrounds) is the direct match. Create the tables a question needs, then try your own approach before revealing the solution.
Open DB Fiddle ↗Opens a third-party SQL playground in a new tab. External site terms and privacy policy apply.
- Read the scenario and try to sketch your own approach before revealing the solution, these are pattern-recognition problems: recursive CTE, gaps-and-islands, interval overlap, running totals.
- Focus on why a technique was chosen, not just memorizing the SQL, the same pattern (e.g. the overlap self-join in questions 16 and 47) shows up across unrelated business domains.
- Where a Production Consideration is shown, treat it as part of the answer, interviewers at this level often ask the follow-up themselves.
- If a real interview or job runs a different database, confirm the actual syntax there too, this set is PostgreSQL 15+ specifically.