0% found this document useful (0 votes)
31 views16 pages

30-Day SQL Practice Guide for Interviews

Uploaded by

adi05229999
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
31 views16 pages

30-Day SQL Practice Guide for Interviews

Uploaded by

adi05229999
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

30-Day SQL Practice Plan

From Beginner to Interview-Ready

Daily problems • Concepts • Solutions

How to Use This Plan:


• Spend 30-60 minutes daily
• Solve problems BEFORE looking at solutions
• Practice on: LeetCode, HackerRank, StrataScratch, SQLZoo
• Week 1: Basics → Week 2: Intermediate → Week 3: Advanced → Week 4: Interview Prep

Week Focus Difficulty

Week 1 (Day 1-7) SELECT, WHERE, ORDER BY, Basic Functions ■ Easy

Week 2 (Day 8-14) JOINs, GROUP BY, HAVING, Subqueries ■ Medium

Week 3 (Day 15-21) Window Functions, CTEs, Advanced Queries ■ Medium-Hard

Week 4 (Day 22-30) Interview Problems, Real Scenarios ■ Hard


WEEK 1: SQL Fundamentals

Focus: SELECT, WHERE, ORDER BY, Basic Functions

■ DAY 1: SELECT Basics


Concepts: SELECT, FROM, * (all columns), specific columns

Problem 1: Retrieve all columns from employees table


■ Easy

SELECT * FROM employees;

Problem 2: Get only name and salary of all employees


■ Easy

SELECT name, salary FROM employees;

Problem 3: Get unique departments from employees table


■ Easy

SELECT DISTINCT department FROM employees;

■ DAY 2: WHERE Clause


Concepts: WHERE, comparison operators (=, >, <, >=, <=, <>)

Problem 1: Find employees with salary greater than 50000


■ Easy

SELECT * FROM employees WHERE salary > 50000;

Problem 2: Find employees in 'Engineering' department


■ Easy

SELECT * FROM employees WHERE department = 'Engineering';

Problem 3: Find products with price between 100 and 500


■ Easy

SELECT * FROM products WHERE price BETWEEN 100 AND 500;


-- OR
SELECT * FROM products WHERE price >= 100 AND price <= 500;

■ DAY 3: AND, OR, NOT, IN, LIKE


Concepts: Multiple conditions, pattern matching

Problem 1: Find employees in Engineering OR Marketing


■ Easy

SELECT * FROM employees


WHERE department = 'Engineering' OR department = 'Marketing';
-- Better way:
SELECT * FROM employees WHERE department IN ('Engineering', 'Marketing');

Problem 2: Find employees whose name starts with 'A'


■ Easy

SELECT * FROM employees WHERE name LIKE 'A%';

Problem 3: Find employees NOT in Sales department with salary > 40000
■ Easy

SELECT * FROM employees


WHERE department <> 'Sales' AND salary > 40000;

■ LIKE patterns: 'A%' (starts with A), '%a' (ends with a), '%kumar%' (contains kumar), '_a%' (second letter is a)
■ DAY 4: ORDER BY & LIMIT
Concepts: Sorting results, limiting rows

Problem 1: Get top 5 highest paid employees


■ Easy

SELECT * FROM employees ORDER BY salary DESC LIMIT 5;

Problem 2: Get employees sorted by department (A-Z), then by salary (high to low)
■ Easy

SELECT * FROM employees


ORDER BY department ASC, salary DESC;

Problem 3: Get the 3rd highest salary (skip first 2)


■ Medium

SELECT DISTINCT salary FROM employees


ORDER BY salary DESC
LIMIT 1 OFFSET 2;

■ DAY 5: Aggregate Functions


Concepts: COUNT, SUM, AVG, MIN, MAX

Problem 1: Count total number of employees


■ Easy

SELECT COUNT(*) AS total_employees FROM employees;

Problem 2: Find average, minimum, and maximum salary


■ Easy

SELECT
AVG(salary) AS avg_salary,
MIN(salary) AS min_salary,
MAX(salary) AS max_salary
FROM employees;

Problem 3: Find total sales amount from orders table


■ Easy

SELECT SUM(amount) AS total_sales FROM orders;

■ DAY 6: NULL Handling


Concepts: IS NULL, IS NOT NULL, COALESCE, IFNULL

Problem 1: Find employees without a manager (manager_id is NULL)


■ Easy

SELECT * FROM employees WHERE manager_id IS NULL;

Problem 2: Find employees who have an email address


■ Easy

SELECT * FROM employees WHERE email IS NOT NULL;

Problem 3: Replace NULL bonus with 0


■ Medium

SELECT name, salary, COALESCE(bonus, 0) AS bonus FROM employees;


-- MySQL: IFNULL(bonus, 0)

■ DAY 7: Week 1 Practice Day


Solve these 5 problems to test your Week 1 learning:

P1: Find all customers from 'Mumbai' or 'Delhi' with orders > 1000
P2: Get top 10 products by price, show name and price only

P3: Count customers who have email addresses

P4: Find employees hired in 2023 (use YEAR function or LIKE)

P5: Calculate total revenue, average order value from orders table
■ Week 1 Complete! You should now be comfortable with basic SELECT queries. Practice more on LeetCode Easy
problems.
WEEK 2: JOINs & Grouping

Focus: All JOIN types, GROUP BY, HAVING, Basic Subqueries

■ DAY 8: INNER JOIN


Concepts: Combining tables on matching values

Problem 1: Get employee names with their department names


■ Medium

SELECT [Link], d.department_name


FROM employees e
INNER JOIN departments d ON e.department_id = [Link];

Problem 2: Get order details with customer names


■ Medium

SELECT o.order_id, [Link], c.customer_name


FROM orders o
INNER JOIN customers c ON o.customer_id = [Link];

Problem 3: Get products with their category names, only where stock > 0
■ Medium

SELECT p.product_name, c.category_name, [Link]


FROM products p
INNER JOIN categories c ON p.category_id = [Link]
WHERE [Link] > 0;

■ DAY 9: LEFT JOIN & RIGHT JOIN


Concepts: Including non-matching rows

Problem 1: Get ALL customers and their orders (including those with no orders)
■ Medium

SELECT c.customer_name, o.order_id, [Link]


FROM customers c
LEFT JOIN orders o ON [Link] = o.customer_id;

Problem 2: Find customers who have NEVER placed an order


■ Medium — Very commonly asked!

SELECT c.customer_name
FROM customers c
LEFT JOIN orders o ON [Link] = o.customer_id
WHERE o.order_id IS NULL;

Problem 3: Find products that have never been ordered


■ Medium

SELECT p.product_name
FROM products p
LEFT JOIN order_items oi ON [Link] = oi.product_id
WHERE [Link] IS NULL;

■ DAY 10: Self JOIN


Concepts: Joining a table with itself

Problem 1: Find employees and their manager names


■ Medium

SELECT [Link] AS employee, [Link] AS manager


FROM employees e
LEFT JOIN employees m ON e.manager_id = [Link];

Problem 2: Find employees who earn MORE than their manager


■ Medium — Classic interview question!

SELECT [Link] AS employee, [Link] AS emp_salary,


[Link] AS manager, [Link] AS mgr_salary
FROM employees e
JOIN employees m ON e.manager_id = [Link]
WHERE [Link] > [Link];
■ DAY 11: GROUP BY Basics
Concepts: Grouping rows, aggregating per group

Problem 1: Count employees in each department


■ Medium

SELECT department, COUNT(*) AS employee_count


FROM employees
GROUP BY department;

Problem 2: Find total sales by each customer


■ Medium

SELECT customer_id, SUM(amount) AS total_spent


FROM orders
GROUP BY customer_id
ORDER BY total_spent DESC;

Problem 3: Find average salary by department


■ Medium

SELECT department,
ROUND(AVG(salary), 2) AS avg_salary
FROM employees
GROUP BY department;

■ DAY 12: HAVING Clause


Concepts: Filtering grouped results (WHERE filters rows, HAVING filters groups)

Problem 1: Find departments with more than 5 employees


■ Medium

SELECT department, COUNT(*) AS emp_count


FROM employees
GROUP BY department
HAVING COUNT(*) > 5;

Problem 2: Find customers who spent more than 10000 total


■ Medium

SELECT customer_id, SUM(amount) AS total


FROM orders
GROUP BY customer_id
HAVING SUM(amount) > 10000;

Problem 3: Find products ordered more than 100 times


■ Medium

SELECT product_id, COUNT(*) AS order_count


FROM order_items
GROUP BY product_id
HAVING COUNT(*) > 100;

■ WHERE vs HAVING: WHERE filters before grouping, HAVING filters after grouping. You can't use aggregate functions
in WHERE.

■ DAY 13: Basic Subqueries


Concepts: Query inside a query

Problem 1: Find employees with salary above average


■ Medium

SELECT name, salary


FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);

Problem 2: Find the second highest salary


■ Medium — Classic!
SELECT MAX(salary) AS second_highest
FROM employees
WHERE salary < (SELECT MAX(salary) FROM employees);

Problem 3: Find employees in the same department as 'Rahul'


■ Medium

SELECT name FROM employees


WHERE department = (
SELECT department FROM employees WHERE name = 'Rahul'
) AND name <> 'Rahul';

■ DAY 14: Week 2 Practice Day


Solve these 5 problems:

P1: Get all orders with customer name and product name (3-table JOIN)

P2: Find departments where average salary > 60000

P3: Find employees who don't have any direct reports

P4: Get monthly sales totals for 2023

P5: Find customers who placed orders above the average order value
■ Week 2 Complete! JOINs and GROUP BY are the bread and butter of SQL interviews. Practice until they feel natural.
WEEK 3: Advanced SQL

Focus: Window Functions, CTEs, Complex Queries

■ DAY 15: Window Functions Intro (ROW_NUMBER, RANK)


Concepts: Calculations across rows without collapsing them

Problem 1: Rank employees by salary


■ Medium-Hard

SELECT name, salary,


RANK() OVER (ORDER BY salary DESC) AS rank,
DENSE_RANK() OVER (ORDER BY salary DESC) AS dense_rank,
ROW_NUMBER() OVER (ORDER BY salary DESC) AS row_num
FROM employees;

Problem 2: Rank employees by salary WITHIN each department


■ Medium-Hard

SELECT name, department, salary,


RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS dept_rank
FROM employees;

■ RANK: 1,1,3 (gaps) | DENSE_RANK: 1,1,2 (no gaps) | ROW_NUMBER: 1,2,3 (unique)

■ DAY 16: Top N Per Group


Concepts: Using window functions for top N problems

Problem 1: Find top 3 highest paid employees in EACH department


■ Medium-Hard — Very common interview question!

SELECT * FROM (
SELECT name, department, salary,
DENSE_RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS rnk
FROM employees
) ranked
WHERE rnk <= 3;

Problem 2: Find the latest order for each customer


■ Medium-Hard

SELECT * FROM (
SELECT customer_id, order_id, order_date, amount,
ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY order_date DESC) AS rn
FROM orders
) t
WHERE rn = 1;

■ DAY 17: LAG & LEAD


Concepts: Accessing previous/next row values

Problem 1: Compare each day's sales with previous day


■ Medium-Hard

SELECT order_date, amount,


LAG(amount, 1) OVER (ORDER BY order_date) AS prev_day,
amount - LAG(amount, 1) OVER (ORDER BY order_date) AS diff
FROM daily_sales;

Problem 2: Calculate month-over-month growth


■ Medium-Hard

SELECT month, revenue,


LAG(revenue) OVER (ORDER BY month) AS prev_month,
ROUND((revenue - LAG(revenue) OVER (ORDER BY month)) * 100.0 /
LAG(revenue) OVER (ORDER BY month), 2) AS growth_pct
FROM monthly_revenue;
■ DAY 18: Running Totals & Moving Averages
Concepts: Cumulative calculations

Problem 1: Calculate running total of sales


■ Medium-Hard

SELECT order_date, amount,


SUM(amount) OVER (ORDER BY order_date) AS running_total
FROM orders;

Problem 2: Calculate 7-day moving average


■ Hard

SELECT order_date, amount,


AVG(amount) OVER (
ORDER BY order_date
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
) AS moving_avg_7day
FROM daily_sales;
■ DAY 19: Common Table Expressions (CTEs)
Concepts: WITH clause, readable complex queries

Problem 1: Find employees earning above department average using CTE


■ Medium-Hard

WITH dept_avg AS (
SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department
)
SELECT [Link], [Link], [Link], d.avg_salary
FROM employees e
JOIN dept_avg d ON [Link] = [Link]
WHERE [Link] > d.avg_salary;

Problem 2: Calculate total and percentage of sales by category


■ Medium-Hard

WITH category_sales AS (
SELECT category, SUM(amount) AS total
FROM sales
GROUP BY category
),
grand_total AS (
SELECT SUM(amount) AS overall FROM sales
)
SELECT [Link], [Link],
ROUND([Link] * 100.0 / [Link], 2) AS percentage
FROM category_sales c, grand_total g;

■ DAY 20: Multiple CTEs & Complex Queries

Problem 1: Year-over-Year comparison with CTEs


■ Hard

WITH yearly_sales AS (
SELECT YEAR(order_date) AS year, SUM(amount) AS total
FROM orders
GROUP BY YEAR(order_date)
),
yoy_comparison AS (
SELECT year, total,
LAG(total) OVER (ORDER BY year) AS prev_year,
total - LAG(total) OVER (ORDER BY year) AS diff
FROM yearly_sales
)
SELECT *, ROUND(diff * 100.0 / prev_year, 2) AS growth_pct
FROM yoy_comparison;

■ DAY 21: Week 3 Practice Day


Solve these problems:

P1: Find the highest selling product in each category

P2: Calculate 30-day running total of sales for each customer

P3: Find employees whose salary increased from last year

P4: Rank customers by total purchases and show top 10%

P5: Calculate percentage contribution of each product to total sales


■ Week 3 Complete! Window functions separate good candidates from great ones. Keep practicing!
WEEK 4: Interview-Level Problems

Focus: Real interview questions from top companies

■ DAY 22: Duplicate Detection & Removal

Problem 1: Find duplicate emails


■ Medium

SELECT email, COUNT(*) AS count


FROM users
GROUP BY email
HAVING COUNT(*) > 1;

Problem 2: Delete duplicates, keep lowest ID


■ Hard — Asked at Amazon

DELETE FROM users


WHERE id NOT IN (
SELECT * FROM (
SELECT MIN(id)
FROM users
GROUP BY email
) AS temp
);

■ DAY 23: Consecutive Days/Rows

Problem: Find users who logged in for 3+ consecutive days


■ Hard — Asked at Uber, Airbnb

WITH login_groups AS (
SELECT user_id, login_date,
login_date - INTERVAL ROW_NUMBER() OVER (
PARTITION BY user_id ORDER BY login_date
) DAY AS grp
FROM (SELECT DISTINCT user_id, DATE(login_time) AS login_date FROM logins) t
)
SELECT user_id, MIN(login_date) AS start_date,
MAX(login_date) AS end_date, COUNT(*) AS streak
FROM login_groups
GROUP BY user_id, grp
HAVING COUNT(*) >= 3;

■ DAY 24: Pivot / Transpose Data

Problem: Convert rows to columns (sales by month)


■ Hard

SELECT product_id,
SUM(CASE WHEN month = 'Jan' THEN amount ELSE 0 END) AS Jan,
SUM(CASE WHEN month = 'Feb' THEN amount ELSE 0 END) AS Feb,
SUM(CASE WHEN month = 'Mar' THEN amount ELSE 0 END) AS Mar
FROM sales
GROUP BY product_id;

■ DAY 25: Finding Gaps in Data

Problem: Find missing IDs in a sequence


■ Hard — Asked at LinkedIn

SELECT [Link] + 1 AS gap_start,


MIN([Link]) - 1 AS gap_end
FROM numbers a
JOIN numbers b ON [Link] < [Link]
WHERE NOT EXISTS (
SELECT 1 FROM numbers c WHERE [Link] = [Link] + 1
)
GROUP BY [Link];

■ DAY 26: Retention & Churn Analysis

Problem: Calculate monthly user retention rate


■ Hard — Product Analytics favorite

WITH monthly_users AS (
SELECT DISTINCT user_id, DATE_FORMAT(activity_date, '%Y-%m') AS month
FROM user_activity
)
SELECT [Link],
COUNT(DISTINCT a.user_id) AS total_users,
COUNT(DISTINCT b.user_id) AS retained_users,
ROUND(COUNT(DISTINCT b.user_id) * 100.0 / COUNT(DISTINCT a.user_id), 2) AS retention_rate
FROM monthly_users a
LEFT JOIN monthly_users b ON a.user_id = b.user_id
AND [Link] = DATE_FORMAT(DATE_ADD(STR_TO_DATE(CONCAT([Link], '-01'), '%Y-%m-%d'), INTERVAL 1 MONTH),
GROUP BY [Link];
■ DAY 27: Median Calculation

Problem: Find median salary


■ Hard

WITH ranked AS (
SELECT salary,
ROW_NUMBER() OVER (ORDER BY salary) AS rn,
COUNT(*) OVER () AS total
FROM employees
)
SELECT AVG(salary) AS median
FROM ranked
WHERE rn IN (FLOOR((total + 1) / 2.0), CEIL((total + 1) / 2.0));

■ DAY 28: Recursive CTEs

Problem: Find entire reporting hierarchy under a manager


■ Hard

WITH RECURSIVE hierarchy AS (


-- Base: start with the top manager
SELECT id, name, manager_id, 1 AS level
FROM employees
WHERE id = 1

UNION ALL

-- Recursive: find all reports


SELECT [Link], [Link], e.manager_id, [Link] + 1
FROM employees e
JOIN hierarchy h ON e.manager_id = [Link]
)
SELECT * FROM hierarchy;

■ DAY 29: Business Case Problems

Problem 1: Find customers who bought A and B but not C


■ Hard

SELECT customer_id
FROM orders
GROUP BY customer_id
HAVING SUM(CASE WHEN product = 'A' THEN 1 ELSE 0 END) > 0
AND SUM(CASE WHEN product = 'B' THEN 1 ELSE 0 END) > 0
AND SUM(CASE WHEN product = 'C' THEN 1 ELSE 0 END) = 0;

Problem 2: Find products with declining sales for 3 consecutive months


■ Hard

WITH monthly AS (
SELECT product_id, month, total,
LAG(total, 1) OVER (PARTITION BY product_id ORDER BY month) AS prev1,
LAG(total, 2) OVER (PARTITION BY product_id ORDER BY month) AS prev2
FROM monthly_sales
)
SELECT product_id, month
FROM monthly
WHERE total < prev1 AND prev1 < prev2;

■ DAY 30: Final Challenge Day!


Solve these without looking at solutions. Time yourself (45 mins).

Challenge 1: Top 3 salaries in each department

Challenge 2: Employees earning more than department average

Challenge 3: Second highest salary (handle ties)


Challenge 4: Running total of sales by customer

Challenge 5: Find managers with at least 5 direct reports


Practice Resources

Platform Best For Link

LeetCode Interview prep [Link]/problemset/database

HackerRank Beginners [Link]/domains/sql

StrataScratch Real interview Qs [Link]

SQLZoo Interactive learning [Link]

Mode SQL Tutorial Practice datasets [Link]/sql-tutorial

DataLemur FAANG questions [Link]

30-Day Progress Tracker

Print this and check off each day:


■ ■ ■ ■ ■ ■ ■ Week 1
■ ■ ■ ■ ■ ■ ■ Week 2
■ ■ ■ ■ ■ ■ ■ Week 3
■ ■ ■ ■ ■ ■ ■ ■ ■ Week 4

You've completed the 30-Day SQL Challenge! ■ You're now ready to crack SQL interviews. Keep practicing, stay
consistent, and go get that job! ■

You might also like