SQL Interview Questions Cheat Sheet: 21 Patterns You Must Know
Preparing for a SQL interview? This practical cheat sheet shows you the 21 query patterns that keep appearing in data analyst and data engineer interviews – with examples, tips, and mistakes to avoid.
If you're preparing for a SQL interview, you don't need hundreds of random questions.
Most real interviews keep repeating the same patterns:
- Filtering and sorting on realistic tables
- Joining 2–4 tables correctly
- Aggregations with
GROUP BYandHAVING - Window functions for rankings and running totals
- Date logic and time ranges
- Edge cases around NULLs and duplicates
In this guide we'll walk through the most common patterns interviewers use to test whether you're ready for the job.
1. Simple filter with ORDER BY
"Give me active customers from India, sorted by signup date"
Interviewers want to see:
- Clean
WHEREconditions - Correct ordering (often DESC on recent activity)
- Filters that match the business wording
sqlSELECT customer_id, name, country, signup_date FROM customers WHERE status = 'active' AND country = 'India' ORDER BY signup_date DESC;
💡 Tip: Always confirm whether status is a string, enum, or derived flag from another table.
2. INNER JOIN with clear join keys
"List customers and their total order count"
The goal is to check if you:
- Join on the right keys
- Aggregate on the right table
- Avoid double-counting
sqlSELECT c.customer_id, c.name, COUNT(o.order_id) AS total_orders FROM customers c JOIN orders o ON c.customer_id = o.customer_id GROUP BY c.customer_id, c.name;
Common mistakes:
- Missing
GROUP BYcolumns - Joining on non-unique columns and inflating counts
3. LEFT JOIN for optional relationships
"Show all customers and how many orders they placed (including 0)"
This is almost the same as the previous question, but requires a LEFT JOIN:
sqlSELECT c.customer_id, c.name, COUNT(o.order_id) AS total_orders FROM customers c LEFT JOIN orders o ON c.customer_id = o.customer_id GROUP BY c.customer_id, c.name;
💡 Pattern: When the question says "including users who never..." or "even if there are no orders", think LEFT JOIN.
4. GROUP BY with HAVING
"Return products that have been ordered more than 100 times"
sqlSELECT product_id, COUNT(*) AS order_count FROM order_items GROUP BY product_id HAVING COUNT(*) > 100;
Use HAVING when you filter on aggregated values.
5. Top-N per group with window functions
"For each country, find the top 3 customers by total spend"
This is a classic window function pattern:
sqlWITH customer_spend AS ( SELECT c.customer_id, c.country, SUM(o.amount) AS total_spend FROM customers c JOIN orders o ON c.customer_id = o.customer_id GROUP BY c.customer_id, c.country ), ranked AS ( SELECT customer_id, country, total_spend, DENSE_RANK() OVER ( PARTITION BY country ORDER BY total_spend DESC ) AS rnk FROM customer_spend ) SELECT * FROM ranked WHERE rnk <= 3;
If you can confidently explain what PARTITION BY and ORDER BY do here, you're ahead of most candidates.
6. Running totals (cumulative sums)
"Show daily revenue and cumulative revenue over time"
sqlWITH daily_revenue AS ( SELECT order_date, SUM(amount) AS revenue FROM orders GROUP BY order_date ) SELECT order_date, revenue, SUM(revenue) OVER ( ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS cumulative_revenue FROM daily_revenue ORDER BY order_date;
Interviewers use this to test your comfort with window frames.
7. Date range and time filtering
"Count weekly active users for the last 4 weeks"
You'll often see:
DATE_TRUNCin PostgresDATE_FORMATorDATE_ADDin MySQL
sqlSELECT DATE_TRUNC('week', event_time) AS week_start, COUNT(DISTINCT user_id) AS wau FROM user_events WHERE event_time >= NOW() - INTERVAL '28 days' GROUP BY DATE_TRUNC('week', event_time) ORDER BY week_start;
8. Handling NULLs correctly
Questions that mention "missing", "unknown", or "no value" are testing how you handle NULL.
- Use
IS NULL/IS NOT NULL - Be careful with
=and<>(they ignore NULLs)
sqlSELECT * FROM customers WHERE email IS NULL;
9. Real-world join + filter interview question
"Find the top 5 products by revenue in the last 30 days, excluding cancelled orders"
This combines several patterns:
sqlSELECT oi.product_id, SUM(oi.quantity * oi.unit_price) AS revenue FROM order_items oi JOIN orders o ON oi.order_id = o.order_id WHERE o.status <> 'cancelled' AND o.order_date >= CURRENT_DATE - INTERVAL '30 days' GROUP BY oi.product_id ORDER BY revenue DESC LIMIT 5;
If this query feels natural to you, you're very close to being interview-ready.
10. How to practice these patterns the right way
Reading solutions is not enough. Interviewers care about how you think, not just the final query.
When you practice:
- Start from the business question and restate it in your own words.
- Identify the tables and join keys you'll need.
- Decide whether you need aggregations, window functions, or both.
- Write the query step by step instead of trying to be clever in one shot.
If you want structured practice with problems that mirror real interview questions from FAANG and top startups, check out the SQL Interview Preparation Kit on TheQueryLab – it combines:
- Realistic schemas
- Pattern-based questions
- Execution environment you can use directly in your browser
So you don't just memorize solutions – you build intuition.
