Difficulty: Easy

Easy SQL Questions (Entry Level)

These questions test fundamentals — SELECT, WHERE, GROUP BY, basic JOINs. Expected at fresher and 0–2 year experience roles at all companies.

Easy
Find all employees whose salary is greater than the average salary of the company.
TCSInfosys
+
Subquery in WHERE — the inner query calculates the average, the outer query uses it for filtering.
SELECT emp_name, department, salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees)
ORDER BY salary DESC;
Easy
Find the total number of orders and total revenue per product category.
FlipkartMeesho
+
Basic GROUP BY with COUNT and SUM.
SELECT category,
  COUNT(*) total_orders,
  SUM(order_amount) total_revenue
FROM orders
GROUP BY category
ORDER BY total_revenue DESC;
Easy
Write a query to find duplicate emails in a Customers table.
TCSWiproAccenture
+
GROUP BY + HAVING COUNT(*) > 1 finds duplicates.
SELECT email, COUNT(*) AS occurrences
FROM customers
GROUP BY email
HAVING COUNT(*) > 1;
Easy
Find the second highest salary without using LIMIT.
TCSHCLCapgemini
+
Subquery: find MAX where salary < overall MAX.
SELECT MAX(salary) AS second_highest
FROM employees
WHERE salary < (SELECT MAX(salary) FROM employees);
Easy
List all products that have never been ordered.
AmazonMyntra
+
Anti-join: LEFT JOIN orders + WHERE order_id IS NULL.
SELECT p.product_name, p.category
FROM products p
LEFT JOIN order_items oi ON p.id = oi.product_id
WHERE oi.id IS NULL;
Easy
Find the top 3 cities by number of customers.
PaytmOYO
+
GROUP BY city, ORDER BY COUNT DESC, LIMIT 3.
SELECT city, COUNT(*) AS customer_count
FROM customers
GROUP BY city
ORDER BY customer_count DESC
LIMIT 3;
Difficulty: Medium

Medium SQL Questions (1–4 Years Experience)

These require JOINs, CTEs, window functions, subqueries, and multi-step logic. Expected at most product company interviews for analyst roles.

Medium
For each department, find the employee with the highest salary.
AmazonRazorpayPaytm
+
Window function: ROW_NUMBER() PARTITION BY department ORDER BY salary DESC, filter rn=1.
WITH r AS (
  SELECT *,
    ROW_NUMBER() OVER(PARTITION BY department ORDER BY salary DESC) rn
  FROM employees
)
SELECT department, emp_name, salary FROM r WHERE rn = 1;
Medium
Customers who placed orders in January 2024 but NOT in February 2024.
FlipkartSwiggy
+
NOT IN with subquery, or LEFT JOIN with IS NULL on Feb orders.
SELECT DISTINCT customer_id
FROM orders
WHERE EXTRACT(MONTH FROM order_date)=1 AND EXTRACT(YEAR FROM order_date)=2024
  AND customer_id NOT IN (
    SELECT DISTINCT customer_id FROM orders
    WHERE EXTRACT(MONTH FROM order_date)=2 AND EXTRACT(YEAR FROM order_date)=2024
  );
Medium
Calculate cumulative revenue by date (running total).
ZomatoPhonePe
+
SUM OVER with ORDER BY date — no PARTITION needed for overall running total.
SELECT order_date,
  SUM(order_amount) AS daily_revenue,
  SUM(SUM(order_amount)) OVER(ORDER BY order_date) AS cumulative
FROM orders
GROUP BY order_date
ORDER BY order_date;
Medium
Find the percentage each category contributes to total revenue.
WalmartEY
+
SUM with OVER() (no ORDER BY) gives the total across all rows — divide each row’s sum by the total.
SELECT category,
  SUM(order_amount) AS cat_revenue,
  ROUND(SUM(order_amount) * 100.0 / SUM(SUM(order_amount)) OVER(), 2) AS pct
FROM orders
GROUP BY category
ORDER BY pct DESC;
Medium
Find each manager and the count of employees reporting to them.
InfosysAccenture
+
Self join — join employees table to itself on manager_id = emp_id.
SELECT m.emp_name AS manager, COUNT(e.emp_id) AS direct_reports
FROM employees e
JOIN employees m ON e.manager_id = m.emp_id
GROUP BY m.emp_name
ORDER BY direct_reports DESC;
Difficulty: Hard

Hard SQL Questions (Senior/Advanced)

Multi-step complex queries tested at Google, Amazon, Meta, Flipkart for senior analyst, analytics engineer, and data scientist roles.

Hard
Find users who made purchases on 3 or more consecutive days in the last 30 days.
GoogleMetaUber
+
Classic consecutive days trick: subtract ROW_NUMBER from date to create a group key.
WITH da AS (
  SELECT DISTINCT user_id, DATE(purchase_date) dt
  FROM purchases WHERE purchase_date >= CURRENT_DATE-30
), grp AS (
  SELECT user_id, dt,
    dt – ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY dt)::integer g
  FROM da
)
SELECT DISTINCT user_id
FROM grp
GROUP BY user_id, g
HAVING COUNT(*)>=3;
Hard
Calculate 7-day rolling average DAU for each product.
GoogleAirbnbWalmart
+
AVG OVER with ROWS BETWEEN 6 PRECEDING AND CURRENT ROW.
SELECT product_id, dt, dau,
  AVG(dau) OVER(
    PARTITION BY product_id ORDER BY dt
    ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
  ) rolling_7d_avg
FROM dau_table
ORDER BY product_id, dt;
Hard
Find the first purchase date and second purchase date for each customer, and the gap between them.
AmazonMeesho
+
ROW_NUMBER + LEAD or two CTEs filtering rn=1 and rn=2, then join.
WITH ranked AS (
  SELECT customer_id, order_date,
    ROW_NUMBER() OVER(PARTITION BY customer_id ORDER BY order_date) rn
  FROM orders
)
SELECT
  MAX(CASE WHEN rn=1 THEN order_date END) first_order,
  MAX(CASE WHEN rn=2 THEN order_date END) second_order,
  MAX(CASE WHEN rn=2 THEN order_date END)
     MAX(CASE WHEN rn=1 THEN order_date END) gap_days
FROM ranked
GROUP BY customer_id;
Exam Strategy

SQL Interview Tips That Actually Work

  • Think out loud — interviewers evaluate your process, not just your answer. Say ‘I’ll GROUP BY category and then filter with HAVING’ before you write it.
  • Clarify before coding — ask about edge cases: Are there NULLs? Can a customer have multiple orders on the same day? This shows analytical maturity.
  • Verify with examples — after writing, trace through 2-3 rows mentally. If your window function produces the right rank for your sample, you’re probably right.
  • Know RANK vs ROW_NUMBER — the #1 mistake is using RANK when you need exactly 1 row per group. Always clarify: should ties be included?
  • Use CTEs, not deep nesting — a query with 3 named CTEs shows you write readable SQL. A 5-level nested subquery makes interviewers nervous.
  • Name your aliases clearly — rev_2024, customer_count, avg_order are better than a, b, x. Interviewers read your aliases to understand your intent.

Practice with a real interviewer

Book a free SQL mock session. We’ll run you through company-specific questions and give detailed feedback on your approach.

Book Free Session