100 Must-Know MySQL Interview Questions & Solutions (Employees Dataset)
Table of Contents
100 MySQL Practice Questions & Answers⌗
A comprehensive, production-grade collection of 100 real-world SQL interview questions and battle-tested solutions built directly on the official MySQL employees relational database.
[!tip] 🚀 Practice Online in Your Browser (No Setup / Installation Required) Practicing on a work/restricted laptop without MySQL installed? You can run and practice all these queries live with the preloaded dataset right in your browser: 👉 Open the Web SQL Playground (Runs 100% in-browser, preloaded with Employees & ClassicModels data).
[!info] Quick Navigation
- Part 1: Basic SELECT, Filtering & Sorting (Q1 – Q15)
- Part 2: String & Date Functions (Q16 – Q30)
- Part 3: Aggregations, GROUP BY & HAVING (Q31 – Q45)
- Part 4: Relational Joins Mastery (Q46 – Q60)
- Part 5: Subqueries, CTEs & Set Operations (Q61 – Q75)
- Part 6: Window Functions & Analytical SQL (Q76 – Q90)
- Part 7: Advanced Business Logic & Edge Cases (Q91 – Q100)
🛠️ Schema Relationship Cheat Sheet⌗
employees (emp_no)
│
├──< dept_emp (emp_no, dept_no) >── departments (dept_no)
│
├──< dept_manager (emp_no, dept_no) >── departments (dept_no)
│
├──< salaries (emp_no, salary, from_date, to_date)
│
└──< titles (emp_no, title, from_date, to_date)
[!tip] Active Records Rule in Employees Dataset Active department assignments, titles, and salaries are marked by
to_date = '9999-01-01'.
🟢 Part 1: Basic SELECT, Filtering & Sorting⌗
Focus: Fundamental filtering, comparison operators, and projection.
Q1. Employees Hired After 1990⌗
[!question] Problem Statement Select all columns for the first 10 employees hired after January 1, 1990, ordered by hire date ascending.
[!tip] Concepts Tested
WHERE, Date Comparison,ORDER BY,LIMIT
[!success]- Reveal SQL Solution
SELECT * FROM employees WHERE hire_date > '1990-01-01' ORDER BY hire_date ASC LIMIT 10;Explanation: Filters rows using
WHERE hire_date > '1990-01-01', sorts the dataset chronologically withORDER BY hire_date ASC, and limits the output to the first 10 records.
Q2. All Distinct Historical Job Titles⌗
[!question] Problem Statement Retrieve all unique job titles ever held by employees across the entire organization.
[!tip] Concepts Tested
SELECT DISTINCT, Column Projection
[!success]- Reveal SQL Solution
SELECT DISTINCT title FROM titles ORDER BY title ASC;Explanation: Uses
DISTINCTto eliminate duplicate title entries across historical employment records, returning each distinct job position.
Q3. Pattern Matching on First and Last Names⌗
[!question] Problem Statement Find all employees whose first name starts with ‘B’ and whose last name ends with ’s’.
[!tip] Concepts Tested
LIKEWildcard Matching (%), LogicalAND
[!success]- Reveal SQL Solution
SELECT emp_no, first_name, last_name, gender, hire_date FROM employees WHERE first_name LIKE 'B%' AND last_name LIKE '%s';Explanation:
'B%'matches any string beginning with uppercase ‘B’, while'%s'matches any string ending in ’s’.
Q4. Female Employees Hired in Late 80s⌗
[!question] Problem Statement List all female employees (
gender = 'F') hired between January 1, 1985 and December 31, 1989.
[!tip] Concepts Tested
BETWEEN ... AND ..., Equality Filter
[!success]- Reveal SQL Solution
SELECT emp_no, first_name, last_name, gender, hire_date FROM employees WHERE gender = 'F' AND hire_date BETWEEN '1985-01-01' AND '1989-12-31' ORDER BY hire_date ASC;Explanation:
BETWEENis inclusive on both boundaries (1985-01-01and1989-12-31).
Q5. Substring Search in First Names⌗
[!question] Problem Statement Find all employees whose
first_namecontains the substring ‘ar’ anywhere within the name.
[!tip] Concepts Tested
LIKE '%ar%'(Case-Insensitive in default collation)
[!success]- Reveal SQL Solution
SELECT emp_no, first_name, last_name FROM employees WHERE first_name LIKE '%ar%' ORDER BY first_name ASC;Explanation: The surrounding
%wildcards allow any characters before and after ‘ar’.
Q6. Top 5 Highest Salaries Ever Recorded⌗
[!question] Problem Statement Retrieve the top 5 highest distinct salary values recorded in company history.
[!tip] Concepts Tested
DISTINCT,ORDER BY DESC,LIMIT
[!success]- Reveal SQL Solution
SELECT DISTINCT salary FROM salaries ORDER BY salary DESC LIMIT 5;Explanation: Orders the
salariestable in descending order and returns the 5 highest historical compensation levels.
Q7. Long Department Names⌗
[!question] Problem Statement Find all departments that have a
dept_namelonger than 15 characters.
[!tip] Concepts Tested
CHAR_LENGTH()vsLENGTH()
[!success]- Reveal SQL Solution
SELECT dept_no, dept_name, CHAR_LENGTH(dept_name) AS name_length FROM departments WHERE CHAR_LENGTH(dept_name) > 15;Explanation:
CHAR_LENGTH()counts characters rather than bytes, making it safe for multi-byte Unicode strings.
Q8. Active Employees Outside Department d005⌗
[!question] Problem Statement Select all currently assigned employees who do not belong to department ‘d005’.
[!tip] Concepts Tested
!=or<>, Active Record Filtering (to_date = '9999-01-01')
[!success]- Reveal SQL Solution
SELECT emp_no, dept_no, from_date, to_date FROM dept_emp WHERE dept_no <> 'd005' AND to_date = '9999-01-01';Explanation: In the MySQL employees sample database, active status is represented by
to_date = '9999-01-01'.<>denotes inequality.
Q9. Current Salaries in 60k to 70k Range⌗
[!question] Problem Statement Retrieve all active salary records where the compensation is between $60,000 and $70,000 inclusive.
[!tip] Concepts Tested
BETWEEN, Active Record Filter
[!success]- Reveal SQL Solution
SELECT emp_no, salary, from_date, to_date FROM salaries WHERE salary BETWEEN 60000 AND 70000 AND to_date = '9999-01-01' ORDER BY salary DESC;Explanation: Combines active date filtering (
to_date = '9999-01-01') with an inclusive numeric range check.
Q10. Employees Born in February⌗
[!question] Problem Statement Find all employees who were born in the month of February, regardless of year.
[!tip] Concepts Tested
MONTH()orEXTRACT(MONTH FROM ...)
[!success]- Reveal SQL Solution
SELECT emp_no, first_name, last_name, birth_date FROM employees WHERE MONTH(birth_date) = 2;Explanation:
MONTH(birth_date)extracts the 1-indexed calendar month (1=Jan, 2=Feb).
Q11. Engineering and Management Titles⌗
[!question] Problem Statement List all unique job titles that include the words ‘Engineer’ or ‘Manager’.
[!tip] Concepts Tested
LIKE, LogicalOR
[!success]- Reveal SQL Solution
SELECT DISTINCT title FROM titles WHERE title LIKE '%Engineer%' OR title LIKE '%Manager%' ORDER BY title ASC;Explanation: Searches title variations like ‘Senior Engineer’, ‘Assistant Engineer’, and ‘Manager’.
Q12. Round Number Salaries⌗
[!question] Problem Statement Find all distinct historical salary amounts that are exact multiples of 1,000 (e.g., 65000, 72000).
[!tip] Concepts Tested Modulo Operator
MOD()or%
[!success]- Reveal SQL Solution
SELECT DISTINCT salary FROM salaries WHERE salary % 1000 = 0 ORDER BY salary DESC;Explanation:
salary % 1000 = 0checks that the salary has zero remainder when divided by 1,000.
Q13. The 10 Oldest Employees⌗
[!question] Problem Statement Retrieve the 10 oldest employees in the database based on their birth date.
[!tip] Concepts Tested
ORDER BY birth_date ASC,LIMIT
[!success]- Reveal SQL Solution
SELECT emp_no, first_name, last_name, birth_date, hire_date FROM employees ORDER BY birth_date ASC LIMIT 10;Explanation: Ascending sort on birth date places earlier dates (older individuals) at the top.
Q14. Currently Active Department Managers⌗
[!question] Problem Statement Find all department managers who are currently active.
[!tip] Concepts Tested Equality check on open-ended date literal
[!success]- Reveal SQL Solution
SELECT emp_no, dept_no, from_date, to_date FROM dept_manager WHERE to_date = '9999-01-01';Explanation: In this schema,
dept_managerrecords withto_date = '9999-01-01'signify active assignments.
Q15. Equal Length First and Last Names⌗
[!question] Problem Statement List all employees whose first name and last name have the exact same character count.
[!tip] Concepts Tested
CHAR_LENGTH(), Column-to-Column Comparison
[!success]- Reveal SQL Solution
SELECT emp_no, first_name, last_name, CHAR_LENGTH(first_name) AS name_len FROM employees WHERE CHAR_LENGTH(first_name) = CHAR_LENGTH(last_name) LIMIT 20;Explanation: Compares the character lengths of two distinct columns on each row.
🟢 Part 2: String & Date Functions⌗
Focus: String manipulation, date math, age calculations, and temporal patterns.
Q16. Formatted Full Name (LASTNAME, Firstname)⌗
[!question] Problem Statement Display each employee’s full name in the format: ‘LASTNAME, Firstname’ (e.g. ‘SMITH, John’).
[!tip] Concepts Tested
CONCAT(),UPPER()
[!success]- Reveal SQL Solution
SELECT emp_no, CONCAT(UPPER(last_name), ', ', first_name) AS formal_name FROM employees LIMIT 15;Explanation: Converts
last_nameto uppercase and concatenates it with a comma, space, and the capitalized first name.
Q17. Current Employee Age⌗
[!question] Problem Statement Calculate the current age in complete years for every employee as of today.
[!tip] Concepts Tested
TIMESTAMPDIFF(),CURDATE()
[!success]- Reveal SQL Solution
SELECT emp_no, first_name, last_name, birth_date, TIMESTAMPDIFF(YEAR, birth_date, CURDATE()) AS current_age FROM employees LIMIT 15;Explanation:
TIMESTAMPDIFF(YEAR, d1, d2)accurately calculates whole elapsed calendar years between two dates without leap-year rounding errors.
Q18. Hire Age in Years⌗
[!question] Problem Statement Calculate how old each employee was when they were hired.
[!tip] Concepts Tested
TIMESTAMPDIFF()with two date columns
[!success]- Reveal SQL Solution
SELECT emp_no, first_name, last_name, birth_date, hire_date, TIMESTAMPDIFF(YEAR, birth_date, hire_date) AS age_at_hire FROM employees LIMIT 15;Explanation: Calculates elapsed years between
birth_dateandhire_date.
Q19. Employees Hired on Mondays⌗
[!question] Problem Statement Find all employees who were hired on a Monday.
[!tip] Concepts Tested
DAYNAME()orWEEKDAY()
[!success]- Reveal SQL Solution
SELECT emp_no, first_name, last_name, hire_date, DAYNAME(hire_date) AS day_of_week FROM employees WHERE DAYNAME(hire_date) = 'Monday' LIMIT 15;Explanation:
DAYNAME(hire_date)returns the full English name of the day (e.g., ‘Monday’).
Q20. Custom Date Formatting⌗
[!question] Problem Statement Format each employee’s hire date as ‘Mon DD, YYYY’ (e.g., ‘Jan 15, 1990’).
[!tip] Concepts Tested
DATE_FORMAT()specifiers (%b,%d,%Y)
[!success]- Reveal SQL Solution
SELECT emp_no, first_name, last_name, DATE_FORMAT(hire_date, '%b %d, %Y') AS formatted_hire_date FROM employees LIMIT 15;Explanation:
%bgives 3-letter month abbreviation,%dgives 2-digit day, and%Ygives 4-digit year.
Q21. Employees with Over 30 Years of Service⌗
[!question] Problem Statement Find all employees whose tenure exceeds 30 years from their hire date.
[!tip] Concepts Tested
DATE_SUB()orINTERVALDate Arithmetic
[!success]- Reveal SQL Solution
SELECT emp_no, first_name, last_name, hire_date FROM employees WHERE hire_date <= DATE_SUB(CURDATE(), INTERVAL 30 YEAR) ORDER BY hire_date ASC LIMIT 15;Explanation:
DATE_SUB(CURDATE(), INTERVAL 30 YEAR)calculates the cutoff date 30 years prior to today.
Q22. Generate Corporate Email Addresses⌗
[!question] Problem Statement Generate a standardized corporate email address in all lowercase:
firstname.lastname@company.com.
[!tip] Concepts Tested
LOWER(),CONCAT()
[!success]- Reveal SQL Solution
SELECT emp_no, LOWER(CONCAT(first_name, '.', last_name, '@company.com')) AS corporate_email FROM employees LIMIT 15;Explanation:
LOWER()converts all characters to lowercase after string concatenation.
Q23. First Names with Odd Character Counts⌗
[!question] Problem Statement Find all employees whose first name contains an odd number of characters.
[!tip] Concepts Tested
CHAR_LENGTH(),MOD()
[!success]- Reveal SQL Solution
SELECT emp_no, first_name, CHAR_LENGTH(first_name) AS name_len FROM employees WHERE MOD(CHAR_LENGTH(first_name), 2) = 1 LIMIT 15;Explanation:
MOD(val, 2) = 1checks for odd integers.
Q24. Birth Decade Distribution⌗
[!question] Problem Statement Count the total number of employees born in each decade (1950s, 1960s).
[!tip] Concepts Tested
FLOOR(),YEAR(),GROUP BY
[!success]- Reveal SQL Solution
SELECT FLOOR(YEAR(birth_date) / 10) * 10 AS birth_decade, COUNT(*) AS total_employees FROM employees GROUP BY birth_decade ORDER BY birth_decade ASC;Explanation: Dividing by 10, applying
FLOOR(), and multiplying by 10 groups years into round 10-year decade buckets.
Q25. First and Last Day of Hire Month⌗
[!question] Problem Statement For each employee, compute the first calendar day and last calendar day of the month they were hired.
[!tip] Concepts Tested
DATE_FORMAT(),LAST_DAY()
[!success]- Reveal SQL Solution
SELECT emp_no, hire_date, DATE_FORMAT(hire_date, '%Y-%m-01') AS first_of_month, LAST_DAY(hire_date) AS last_of_month FROM employees LIMIT 15;Explanation:
DATE_FORMAT(date, '%Y-%m-01')forces the first day of the month, whileLAST_DAY(date)calculates the month’s final day.
Q26. Masking Employee IDs⌗
[!question] Problem Statement Mask employee numbers showing only the last 3 digits prefixed by asterisks (e.g. ‘***123’).
[!tip] Concepts Tested
RIGHT(),CONCAT()
[!success]- Reveal SQL Solution
SELECT emp_no, CONCAT('***', RIGHT(emp_no, 3)) AS masked_id, first_name, last_name FROM employees LIMIT 15;Explanation:
RIGHT(emp_no, 3)extracts the trailing 3 digits.
Q27. Job Title Tenure in Days⌗
[!question] Problem Statement Calculate the tenure (in days) between
from_dateandto_datefor past title assignments.
[!tip] Concepts Tested
DATEDIFF()
[!success]- Reveal SQL Solution
SELECT emp_no, title, from_date, to_date, DATEDIFF(to_date, from_date) AS tenure_in_days FROM titles WHERE to_date <> '9999-01-01' ORDER BY tenure_in_days DESC LIMIT 15;Explanation:
DATEDIFF(d1, d2)computesd1 - d2in whole calendar days.
Q28. Shared Birthday Analysis⌗
[!question] Problem Statement Find which calendar days (month and day) have the highest count of employee birthdays.
[!tip] Concepts Tested
MONTH(),DAY(),GROUP BY,HAVING
[!success]- Reveal SQL Solution
SELECT MONTH(birth_date) AS b_month, DAY(birth_date) AS b_day, COUNT(*) AS employee_count FROM employees GROUP BY b_month, b_day HAVING employee_count > 1 ORDER BY employee_count DESC LIMIT 10;Explanation: Groups by month and day together, ignoring birth year.
Q29. Employees Hired on Their Birthday⌗
[!question] Problem Statement Identify employees who were hired on the exact anniversary of their birthday.
[!tip] Concepts Tested Comparing
MONTH()andDAY()across two columns
[!success]- Reveal SQL Solution
SELECT emp_no, first_name, last_name, birth_date, hire_date FROM employees WHERE MONTH(birth_date) = MONTH(hire_date) AND DAY(birth_date) = DAY(hire_date) LIMIT 15;Explanation: Compares the calendar month and day components between
birth_dateandhire_date.
Q30. Sanitizing Department Names⌗
[!question] Problem Statement Replace all spaces and hyphens in department names with underscores.
[!tip] Concepts Tested Nested
REPLACE()calls
[!success]- Reveal SQL Solution
SELECT dept_no, dept_name, REPLACE(REPLACE(dept_name, ' ', '_'), '-', '_') AS sanitized_name FROM departments;Explanation: Chains
REPLACE()calls to sanitize string characters sequentially.
🟢 Part 3: Aggregations, GROUP BY & HAVING⌗
Focus: Descriptive statistics, multi-tier grouping, aggregate filters, and ROLLUP.
Q31. Gender Headcount and Percentage⌗
[!question] Problem Statement Find the total count and overall percentage of male and female employees.
[!tip] Concepts Tested
COUNT(), Subquery for percentage calculation
[!success]- Reveal SQL Solution
SELECT gender, COUNT(*) AS total_employees, ROUND(COUNT(*) * 100.0 / (SELECT COUNT(*) FROM employees), 2) AS percentage FROM employees GROUP BY gender;Explanation: Uses a scalar subquery
(SELECT COUNT(*) FROM employees)in the expression to compute proportional percentage.
Q32. Hires Per Calendar Year⌗
[!question] Problem Statement Count the total number of employees hired each year, ordered chronologically.
[!tip] Concepts Tested
YEAR(),GROUP BY,ORDER BY
[!success]- Reveal SQL Solution
SELECT YEAR(hire_date) AS hire_year, COUNT(*) AS hires_count FROM employees GROUP BY hire_year ORDER BY hire_year ASC;Explanation: Aggregates total hires grouped by the extracted
hire_year.
Q33. Current Overall Salary Statistics⌗
[!question] Problem Statement Calculate the overall average, minimum, maximum, and total current compensation across all active employees.
[!tip] Concepts Tested
AVG(),MIN(),MAX(),SUM(),ROUND()
[!success]- Reveal SQL Solution
SELECT COUNT(*) AS active_payroll_count, MIN(salary) AS min_salary, MAX(salary) AS max_salary, ROUND(AVG(salary), 2) AS avg_salary, SUM(salary) AS total_payroll FROM salaries WHERE to_date = '9999-01-01';Explanation: Calculates foundational descriptive statistics over the active salary population.
Q34. Headcount by Active Job Title⌗
[!question] Problem Statement Find the total number of employees currently holding each job title.
[!tip] Concepts Tested
GROUP BY, Active filter
[!success]- Reveal SQL Solution
SELECT title, COUNT(*) AS active_holders FROM titles WHERE to_date = '9999-01-01' GROUP BY title ORDER BY active_holders DESC;Explanation: Aggregates active employees per title.
Q35. Departments with Over 15,000 Active Employees⌗
[!question] Problem Statement Find department IDs that currently have more than 15,000 active employees assigned.
[!tip] Concepts Tested
GROUP BY,HAVING
[!success]- Reveal SQL Solution
SELECT dept_no, COUNT(*) AS active_headcount FROM dept_emp WHERE to_date = '9999-01-01' GROUP BY dept_no HAVING active_headcount > 15000 ORDER BY active_headcount DESC;Explanation:
HAVINGfilters group-level aggregate counts afterGROUP BYexecution.
Q36. Average Current Salary by Department⌗
[!question] Problem Statement Calculate the average current salary for each department.
[!tip] Concepts Tested 3-table
JOIN,GROUP BY,AVG()
[!success]- Reveal SQL Solution
SELECT d.dept_no, d.dept_name, ROUND(AVG(s.salary), 2) AS average_salary FROM departments d JOIN dept_emp de ON d.dept_no = de.dept_no JOIN salaries s ON de.emp_no = s.emp_no WHERE de.to_date = '9999-01-01' AND s.to_date = '9999-01-01' GROUP BY d.dept_no, d.dept_name ORDER BY average_salary DESC;Explanation: Joins
departments,dept_emp, andsalariesfiltering both membership and compensation to active terms.
Q37. Titles with Average Salary Above $75,000⌗
[!question] Problem Statement List all job titles whose current average salary exceeds $75,000.
[!tip] Concepts Tested
JOIN,GROUP BY,HAVING
[!success]- Reveal SQL Solution
SELECT t.title, ROUND(AVG(s.salary), 2) AS avg_title_salary FROM titles t JOIN salaries s ON t.emp_no = s.emp_no WHERE t.to_date = '9999-01-01' AND s.to_date = '9999-01-01' GROUP BY t.title HAVING avg_title_salary > 75000 ORDER BY avg_title_salary DESC;Explanation: Filters aggregated salary averages using
HAVING avg_title_salary > 75000.
Q38. Employees with the Most Salary Raises⌗
[!question] Problem Statement Find employees who have received the highest number of historical salary adjustments.
[!tip] Concepts Tested
COUNT(*) - 1,GROUP BY
[!success]- Reveal SQL Solution
SELECT emp_no, COUNT(*) - 1 AS raise_count FROM salaries GROUP BY emp_no HAVING raise_count >= 15 ORDER BY raise_count DESC LIMIT 10;Explanation: An employee with $N$ salary records has received $N - 1$ salary increases/adjustments.
Q39. Department Salary Spread (> $50,000)⌗
[!question] Problem Statement Find departments where the spread (max minus min current salary) exceeds $50,000.
[!tip] Concepts Tested
MAX() - MIN(),HAVING
[!success]- Reveal SQL Solution
SELECT d.dept_name, MIN(s.salary) AS min_sal, MAX(s.salary) AS max_sal, (MAX(s.salary) - MIN(s.salary)) AS salary_spread FROM departments d JOIN dept_emp de ON d.dept_no = de.dept_no JOIN salaries s ON de.emp_no = s.emp_no WHERE de.to_date = '9999-01-01' AND s.to_date = '9999-01-01' GROUP BY d.dept_name HAVING salary_spread > 50000 ORDER BY salary_spread DESC;Explanation: Evaluates the wage disparity within each department.
Q40. High Volume Hiring Years (> 1,000 Hires)⌗
[!question] Problem Statement Identify the years in which the company hired more than 1,000 employees.
[!tip] Concepts Tested
YEAR(),COUNT(),HAVING
[!success]- Reveal SQL Solution
SELECT YEAR(hire_date) AS hire_year, COUNT(*) AS total_hires FROM employees GROUP BY hire_year HAVING total_hires > 1000 ORDER BY total_hires DESC;Explanation: Filters years based on aggregated recruitment volume.
Q41. Total Active Payroll by Department⌗
[!question] Problem Statement Calculate the total annualized payroll budget for each department for all active employees.
[!tip] Concepts Tested
SUM(),GROUP BY
[!success]- Reveal SQL Solution
SELECT d.dept_name, SUM(s.salary) AS total_payroll_expenditure FROM departments d JOIN dept_emp de ON d.dept_no = de.dept_no JOIN salaries s ON de.emp_no = s.emp_no WHERE de.to_date = '9999-01-01' AND s.to_date = '9999-01-01' GROUP BY d.dept_name ORDER BY total_payroll_expenditure DESC;Explanation: Sums active individual salaries grouped by department name.
Q42. Employees with 3 or More Distinct Titles⌗
[!question] Problem Statement Identify all employees who have held at least 3 distinct job titles in their career.
[!tip] Concepts Tested
COUNT(DISTINCT title),HAVING
[!success]- Reveal SQL Solution
SELECT emp_no, COUNT(DISTINCT title) AS distinct_titles_count FROM titles GROUP BY emp_no HAVING distinct_titles_count >= 3 ORDER BY distinct_titles_count DESC LIMIT 15;Explanation:
COUNT(DISTINCT title)prevents multiple records with the same title from inflating the count.
Q43. Average Starting Salary by Birth Decade⌗
[!question] Problem Statement Calculate the average initial starting salary for employees grouped by birth decade.
[!tip] Concepts Tested Subquery for initial salary +
GROUP BY
[!success]- Reveal SQL Solution
WITH InitialSalaries AS ( SELECT emp_no, salary AS starting_salary FROM salaries WHERE (emp_no, from_date) IN ( SELECT emp_no, MIN(from_date) FROM salaries GROUP BY emp_no ) ) SELECT FLOOR(YEAR(e.birth_date) / 10) * 10 AS birth_decade, ROUND(AVG(i.starting_salary), 2) AS avg_initial_salary FROM employees e JOIN InitialSalaries i ON e.emp_no = i.emp_no GROUP BY birth_decade ORDER BY birth_decade ASC;Explanation: Uses a CTE to isolate each employee’s earliest salary record, then computes decade averages.
Q44. Department with the Highest Turnover of Managers⌗
[!question] Problem Statement Find the department that has had the highest total number of managers across history.
[!tip] Concepts Tested
COUNT(*),ORDER BY DESC,LIMIT 1
[!success]- Reveal SQL Solution
SELECT d.dept_no, d.dept_name, COUNT(*) AS total_managers_count FROM departments d JOIN dept_manager dm ON d.dept_no = dm.dept_no GROUP BY d.dept_no, d.dept_name ORDER BY total_managers_count DESC LIMIT 1;Explanation: Counts historical manager rows per department.
Q45. Department & Gender Subtotals (WITH ROLLUP)⌗
[!question] Problem Statement Compute employee count subtotals and grand totals across department and gender using
WITH ROLLUP.
[!tip] Concepts Tested
GROUP BY ... WITH ROLLUP,IFNULL()
[!success]- Reveal SQL Solution
SELECT IFNULL(d.dept_name, '-- COMPANY TOTAL --') AS department, IFNULL(e.gender, '-- ALL GENDERS --') AS gender, COUNT(*) AS employee_count FROM employees e JOIN dept_emp de ON e.emp_no = de.emp_no JOIN departments d ON de.dept_no = d.dept_no WHERE de.to_date = '9999-01-01' GROUP BY d.dept_name, e.gender WITH ROLLUP;Explanation:
WITH ROLLUPadds hierarchical subtotal and grand total rows to the grouped result.
🟢 Part 4: Relational Joins Mastery⌗
Focus: Multi-table joins, self-joins, anti-joins, and relational modeling.
Q46. Current Employee Title and Salary⌗
[!question] Problem Statement List each employee’s full name, current job title, and current salary.
[!tip] Concepts Tested Multi-table
INNER JOIN
[!success]- Reveal SQL Solution
SELECT e.emp_no, CONCAT(e.first_name, ' ', e.last_name) AS full_name, t.title, s.salary FROM employees e JOIN titles t ON e.emp_no = t.emp_no JOIN salaries s ON e.emp_no = s.emp_no WHERE t.to_date = '9999-01-01' AND s.to_date = '9999-01-01' LIMIT 20;Explanation: Joins
employees,titles, andsalariesfiltering to active records.
Q47. Employees and Their Current Department⌗
[!question] Problem Statement Retrieve each employee’s name along with the name of the department they currently work in.
[!tip] Concepts Tested 3-Table
INNER JOIN
[!success]- Reveal SQL Solution
SELECT e.emp_no, CONCAT(e.first_name, ' ', e.last_name) AS full_name, d.dept_name FROM employees e JOIN dept_emp de ON e.emp_no = de.emp_no JOIN departments d ON de.dept_no = d.dept_no WHERE de.to_date = '9999-01-01' LIMIT 20;Explanation: Resolves the Many-to-Many bridge table
dept_empbetweenemployeesanddepartments.
Q48. All Current Department Managers⌗
[!question] Problem Statement Display the full name, department name, and start date of all current department managers.
[!tip] Concepts Tested
JOINondept_manager
[!success]- Reveal SQL Solution
SELECT dm.dept_no, d.dept_name, CONCAT(e.first_name, ' ', e.last_name) AS manager_name, dm.from_date AS managing_since FROM dept_manager dm JOIN departments d ON dm.dept_no = d.dept_no JOIN employees e ON dm.emp_no = e.emp_no WHERE dm.to_date = '9999-01-01';Explanation: Filters
dept_manageronto_date = '9999-01-01'and pulls manager demographic details.
Q49. Employees Alongside Their Current Manager⌗
[!question] Problem Statement Display each employee alongside the full name of their department’s current manager.
[!tip] Concepts Tested Self/Multi-Join involving
dept_empanddept_manager
[!success]- Reveal SQL Solution
SELECT e.emp_no, CONCAT(e.first_name, ' ', e.last_name) AS employee_name, d.dept_name, CONCAT(m.first_name, ' ', m.last_name) AS department_manager FROM employees e JOIN dept_emp de ON e.emp_no = de.emp_no AND de.to_date = '9999-01-01' JOIN departments d ON de.dept_no = d.dept_no JOIN dept_manager dm ON de.dept_no = dm.dept_no AND dm.to_date = '9999-01-01' JOIN employees m ON dm.emp_no = m.emp_no LIMIT 20;Explanation: Joins the
employeestable twice (once aliased asefor the worker, once asmfor their manager).
Q50. Departments Without an Active Manager⌗
[!question] Problem Statement Verify whether any departments currently lack an active manager assignment.
[!tip] Concepts Tested
LEFT JOIN ... WHERE ... IS NULL(Anti-Join)
[!success]- Reveal SQL Solution
SELECT d.dept_no, d.dept_name FROM departments d LEFT JOIN dept_manager dm ON d.dept_no = dm.dept_no AND dm.to_date = '9999-01-01' WHERE dm.emp_no IS NULL;Explanation: An anti-join pattern that flags any department with no active matching
dept_managerrow.
Q51. Employees Who Changed Departments⌗
[!question] Problem Statement Find all employees who have worked in more than one department throughout their career.
[!tip] Concepts Tested
GROUP BY,HAVING COUNT(dept_no) > 1
[!success]- Reveal SQL Solution
SELECT de.emp_no, CONCAT(e.first_name, ' ', e.last_name) AS full_name, COUNT(de.dept_no) AS departments_worked FROM dept_emp de JOIN employees e ON de.emp_no = e.emp_no GROUP BY de.emp_no, full_name HAVING departments_worked > 1 ORDER BY departments_worked DESC LIMIT 15;Explanation: Groups by employee to detect career internal transfers across department boundaries.
Q52. Senior Engineers Earning Less Than Average Engineers⌗
[!question] Problem Statement Find all ‘Senior Engineers’ whose current salary is lower than the current average salary of ‘Engineers’.
[!tip] Concepts Tested Subquery + Multi-table
JOIN
[!success]- Reveal SQL Solution
SELECT e.emp_no, CONCAT(e.first_name, ' ', e.last_name) AS full_name, s.salary FROM employees e JOIN titles t ON e.emp_no = t.emp_no JOIN salaries s ON e.emp_no = s.emp_no WHERE t.title = 'Senior Engineer' AND t.to_date = '9999-01-01' AND s.to_date = '9999-01-01' AND s.salary < ( SELECT AVG(s2.salary) FROM titles t2 JOIN salaries s2 ON t2.emp_no = s2.emp_no WHERE t2.title = 'Engineer' AND t2.to_date = '9999-01-01' AND s2.to_date = '9999-01-01' ) LIMIT 20;Explanation: Compares individual compensation against a benchmark aggregate computed for a lower title tier.
Q53. Longest-Serving Manager per Department⌗
[!question] Problem Statement For each department, find the manager who held the leadership position for the longest duration.
[!tip] Concepts Tested CTE, Window Function
DENSE_RANK(),DATEDIFF()
[!success]- Reveal SQL Solution
WITH ManagerTenures AS ( SELECT dm.dept_no, dm.emp_no, DATEDIFF(IF(dm.to_date = '9999-01-01', CURDATE(), dm.to_date), dm.from_date) AS tenure_days, DENSE_RANK() OVER ( PARTITION BY dm.dept_no ORDER BY DATEDIFF(IF(dm.to_date = '9999-01-01', CURDATE(), dm.to_date), dm.from_date) DESC ) AS rank_order FROM dept_manager dm ) SELECT d.dept_name, CONCAT(e.first_name, ' ', e.last_name) AS longest_serving_manager, mt.tenure_days FROM ManagerTenures mt JOIN departments d ON mt.dept_no = d.dept_no JOIN employees e ON mt.emp_no = e.emp_no WHERE mt.rank_order = 1;Explanation: Calculates tenure in days (substituting
CURDATE()for active terms) and ranks tenures per department.
Q54. Employees Earning More Than Their Current Manager⌗
[!question] Problem Statement Find all active employees who earn a higher current salary than their department’s current manager.
[!tip] Concepts Tested Double Join on
dept_manager&salaries
[!success]- Reveal SQL Solution
SELECT e.emp_no AS employee_id, CONCAT(e.first_name, ' ', e.last_name) AS employee_name, s_emp.salary AS employee_salary, CONCAT(m.first_name, ' ', m.last_name) AS manager_name, s_mgr.salary AS manager_salary, d.dept_name FROM dept_emp de JOIN salaries s_emp ON de.emp_no = s_emp.emp_no AND s_emp.to_date = '9999-01-01' JOIN employees e ON de.emp_no = e.emp_no JOIN departments d ON de.dept_no = d.dept_no JOIN dept_manager dm ON de.dept_no = dm.dept_no AND dm.to_date = '9999-01-01' JOIN salaries s_mgr ON dm.emp_no = s_mgr.emp_no AND s_mgr.to_date = '9999-01-01' JOIN employees m ON dm.emp_no = m.emp_no WHERE de.to_date = '9999-01-01' AND s_emp.salary > s_mgr.salary LIMIT 20;Explanation: Classic organizational interview question comparing staff compensation against management compensation.
Q55. Empty Departments Check⌗
[!question] Problem Statement Check if any department currently has zero active employee assignments.
[!tip] Concepts Tested
LEFT JOIN ... IS NULL
[!success]- Reveal SQL Solution
SELECT d.dept_no, d.dept_name FROM departments d LEFT JOIN dept_emp de ON d.dept_no = de.dept_no AND de.to_date = '9999-01-01' WHERE de.emp_no IS NULL;Explanation: Detects dormant or empty departments.
Q56. Staff with Same Title as Their Department Manager⌗
[!question] Problem Statement Find active employees who hold the exact same job title as their current department manager.
[!tip] Concepts Tested
JOINcomparing two title rows
[!success]- Reveal SQL Solution
SELECT e.emp_no, CONCAT(e.first_name, ' ', e.last_name) AS employee, t_emp.title, d.dept_name FROM dept_emp de JOIN dept_manager dm ON de.dept_no = dm.dept_no JOIN titles t_emp ON de.emp_no = t_emp.emp_no JOIN titles t_mgr ON dm.emp_no = t_mgr.emp_no JOIN employees e ON de.emp_no = e.emp_no JOIN departments d ON de.dept_no = d.dept_no WHERE de.to_date = '9999-01-01' AND dm.to_date = '9999-01-01' AND t_emp.to_date = '9999-01-01' AND t_mgr.to_date = '9999-01-01' AND de.emp_no <> dm.emp_no AND t_emp.title = t_mgr.title LIMIT 20;Explanation: Excludes the manager themselves (
de.emp_no <> dm.emp_no) and checks for title identity.
Q57. Department Peers Hired on the Same Day⌗
[!question] Problem Statement Find pairs of employees who work in the same active department and were hired on the exact same date.
[!tip] Concepts Tested Self-Join with Inequality (
e1.emp_no < e2.emp_no)
[!success]- Reveal SQL Solution
SELECT e1.emp_no AS employee_1, e2.emp_no AS employee_2, de1.dept_no, e1.hire_date FROM employees e1 JOIN employees e2 ON e1.hire_date = e2.hire_date AND e1.emp_no < e2.emp_no JOIN dept_emp de1 ON e1.emp_no = de1.emp_no AND de1.to_date = '9999-01-01' JOIN dept_emp de2 ON e2.emp_no = de2.emp_no AND de2.to_date = '9999-01-01' AND de1.dept_no = de2.dept_no LIMIT 20;Explanation:
e1.emp_no < e2.emp_noprevents pairing an employee with themselves and removes reverse duplicate pairs(A, B)vs(B, A).
Q58. Transfers from Marketing (d001) to Finance (d002)⌗
[!question] Problem Statement Find all employees who transferred directly from Marketing (‘d001’) to Finance (‘d002’).
[!tip] Concepts Tested Self-join on
dept_empwith chronological order
[!success]- Reveal SQL Solution
SELECT de1.emp_no, CONCAT(e.first_name, ' ', e.last_name) AS full_name, de1.from_date AS mkt_start, de2.from_date AS fin_start FROM dept_emp de1 JOIN dept_emp de2 ON de1.emp_no = de2.emp_no JOIN employees e ON de1.emp_no = e.emp_no WHERE de1.dept_no = 'd001' AND de2.dept_no = 'd002' AND de1.from_date < de2.from_date;Explanation: Matches two department records for the same employee where the marketing tenure preceded the finance tenure.
Q59. Starting Salary for Each Title Held⌗
[!question] Problem Statement Retrieve each employee’s salary when they first obtained each of their historical titles.
[!tip] Concepts Tested
JOINonemp_noand matchingfrom_date
[!success]- Reveal SQL Solution
SELECT e.emp_no, t.title, s.salary AS initial_title_salary, t.from_date FROM employees e JOIN titles t ON e.emp_no = t.emp_no JOIN salaries s ON e.emp_no = s.emp_no AND t.from_date = s.from_date LIMIT 20;Explanation: Synchronizes promotion dates with simultaneous compensation updates.
Q60. Unrepresented Title and Department Combinations⌗
[!question] Problem Statement Generate a Cartesian product of all departments and distinct titles to find combinations with zero active employees.
[!tip] Concepts Tested
CROSS JOIN, Anti-Join
[!success]- Reveal SQL Solution
SELECT d.dept_name, t.title FROM departments d CROSS JOIN (SELECT DISTINCT title FROM titles) t LEFT JOIN ( SELECT DISTINCT de.dept_no, ti.title FROM dept_emp de JOIN titles ti ON de.emp_no = ti.emp_no WHERE de.to_date = '9999-01-01' AND ti.to_date = '9999-01-01' ) active_combos ON d.dept_no = active_combos.dept_no AND t.title = active_combos.title WHERE active_combos.dept_no IS NULL;Explanation: Generates all theoretical combinations with
CROSS JOINand subtracts active reality using an anti-join.
🟢 Part 5: Subqueries, CTEs & Set Operations⌗
Focus: Scalar, correlated subqueries, EXISTS, UNION, and common table expressions.
Q61. Single Highest Current Earner (No LIMIT)⌗
[!question] Problem Statement Find the employee who earns the single highest current salary without using
ORDER BY ... LIMIT.
[!tip] Concepts Tested Subquery with
MAX()
[!success]- Reveal SQL Solution
SELECT e.emp_no, CONCAT(e.first_name, ' ', e.last_name) AS full_name, s.salary FROM employees e JOIN salaries s ON e.emp_no = s.emp_no WHERE s.to_date = '9999-01-01' AND s.salary = ( SELECT MAX(salary) FROM salaries WHERE to_date = '9999-01-01' );Explanation: Standard interview test forbidding
LIMITand testing subquery knowledge withMAX().
Q62. Employees Earning Above Company Average⌗
[!question] Problem Statement Find all active employees whose current salary is strictly above the overall company average.
[!tip] Concepts Tested Scalar Subquery in
WHERE
[!success]- Reveal SQL Solution
SELECT e.emp_no, CONCAT(e.first_name, ' ', e.last_name) AS full_name, s.salary FROM employees e JOIN salaries s ON e.emp_no = s.emp_no WHERE s.to_date = '9999-01-01' AND s.salary > ( SELECT AVG(salary) FROM salaries WHERE to_date = '9999-01-01' ) LIMIT 20;Explanation: Compares individual compensation against a scalar aggregate subquery.
Q63. Departments with High Earners (> $100k) Using EXISTS⌗
[!question] Problem Statement Using
EXISTS, list all departments that have at least one active employee earning over $100,000.
[!tip] Concepts Tested Correlated Subquery with
EXISTS
[!success]- Reveal SQL Solution
SELECT d.dept_no, d.dept_name FROM departments d WHERE EXISTS ( SELECT 1 FROM dept_emp de JOIN salaries s ON de.emp_no = s.emp_no WHERE de.dept_no = d.dept_no AND de.to_date = '9999-01-01' AND s.to_date = '9999-01-01' AND s.salary > 100000 );Explanation:
EXISTSterminates as soon as a single matching record is discovered, making it highly efficient.
Q64. Employees Without a Pay Raise (NOT EXISTS)⌗
[!question] Problem Statement Using
NOT EXISTS, find all employees who have only ever had exactly 1 salary record (zero raises).
[!tip] Concepts Tested
NOT EXISTSwith Correlation
[!success]- Reveal SQL Solution
SELECT e.emp_no, CONCAT(e.first_name, ' ', e.last_name) AS full_name, e.hire_date FROM employees e WHERE NOT EXISTS ( SELECT 1 FROM salaries s WHERE s.emp_no = e.emp_no AND s.from_date > e.hire_date ) LIMIT 20;Explanation: Finds workers who have never had a subsequent salary update record after their initial hire date.
Q65. Employees Earning Above Their Department Average⌗
[!question] Problem Statement Find all employees who earn more than the average salary of their own respective department.
[!tip] Concepts Tested Correlated Subquery in
WHERE
[!success]- Reveal SQL Solution
SELECT e.emp_no, CONCAT(e.first_name, ' ', e.last_name) AS full_name, de.dept_no, s.salary FROM employees e JOIN dept_emp de ON e.emp_no = de.emp_no AND de.to_date = '9999-01-01' JOIN salaries s ON e.emp_no = s.emp_no AND s.to_date = '9999-01-01' WHERE s.salary > ( SELECT AVG(s2.salary) FROM dept_emp de2 JOIN salaries s2 ON de2.emp_no = s2.emp_no WHERE de2.dept_no = de.dept_no AND de2.to_date = '9999-01-01' AND s2.to_date = '9999-01-01' ) LIMIT 20;Explanation: Correlates the subquery on
de2.dept_no = de.dept_noto evaluate averages for each row’s department.
Q66. Second Highest Current Salary⌗
[!question] Problem Statement Find the 2nd highest distinct current salary in the company using a subquery.
[!tip] Concepts Tested Subquery with
MAX()
[!success]- Reveal SQL Solution
SELECT MAX(salary) AS second_highest_salary FROM salaries WHERE to_date = '9999-01-01' AND salary < ( SELECT MAX(salary) FROM salaries WHERE to_date = '9999-01-01' );Explanation: The highest value that is strictly less than the overall maximum is the second highest value.
Q67. The Nth Highest Salary (Generic Pattern)⌗
[!question] Problem Statement Write a generic correlated subquery to find the Nth highest current salary (e.g. N = 3).
[!tip] Concepts Tested Correlated Subquery counting higher distinct values
[!success]- Reveal SQL Solution
SELECT DISTINCT s1.salary AS third_highest_salary FROM salaries s1 WHERE to_date = '9999-01-01' AND 2 = ( SELECT COUNT(DISTINCT s2.salary) FROM salaries s2 WHERE s2.to_date = '9999-01-01' AND s2.salary > s1.salary );Explanation: The $N$-th highest value has exactly $N-1$ distinct values greater than itself.
Q68. Employees Holding Both Senior Engineer and Technique Leader⌗
[!question] Problem Statement Find employees who have held both ‘Senior Engineer’ and ‘Technique Leader’ titles.
[!tip] Concepts Tested
INTERSECTorINSubquery
[!success]- Reveal SQL Solution
SELECT emp_no FROM titles WHERE title = 'Senior Engineer' AND emp_no IN ( SELECT emp_no FROM titles WHERE title = 'Technique Leader' ) LIMIT 20;Explanation: Simulates a set intersection identifying individuals appearing in both title sets.
Q69. Initial Salary Higher Than Department Average Initial Salary⌗
[!question] Problem Statement Find employees whose starting salary was strictly greater than their department’s average starting salary.
[!tip] Concepts Tested CTEs with modular aggregation
[!success]- Reveal SQL Solution
WITH FirstSalaries AS ( SELECT emp_no, salary AS start_salary, from_date FROM salaries WHERE (emp_no, from_date) IN ( SELECT emp_no, MIN(from_date) FROM salaries GROUP BY emp_no ) ), DeptStartAverages AS ( SELECT de.dept_no, AVG(fs.start_salary) AS dept_avg_start FROM dept_emp de JOIN FirstSalaries fs ON de.emp_no = fs.emp_no GROUP BY de.dept_no ) SELECT e.emp_no, de.dept_no, fs.start_salary, ROUND(dsa.dept_avg_start, 2) AS dept_avg FROM employees e JOIN dept_emp de ON e.emp_no = de.emp_no AND de.to_date = '9999-01-01' JOIN FirstSalaries fs ON e.emp_no = fs.emp_no JOIN DeptStartAverages dsa ON de.dept_no = dsa.dept_no WHERE fs.start_salary > dsa.dept_avg_start LIMIT 20;Explanation: Modularizes starting salary discovery and department benchmark calculations using CTEs.
Q70. Managers and $120k+ Earners (UNION)⌗
[!question] Problem Statement Combine the distinct list of all current managers and all employees earning over $120,000.
[!tip] Concepts Tested
UNION(Set Union)
[!success]- Reveal SQL Solution
SELECT e.emp_no, CONCAT(e.first_name, ' ', e.last_name) AS full_name, 'Department Manager' AS qualifying_reason FROM dept_manager dm JOIN employees e ON dm.emp_no = e.emp_no WHERE dm.to_date = '9999-01-01' UNION SELECT e.emp_no, CONCAT(e.first_name, ' ', e.last_name) AS full_name, 'High Earner (>120k)' AS qualifying_reason FROM salaries s JOIN employees e ON s.emp_no = e.emp_no WHERE s.to_date = '9999-01-01' AND s.salary > 120000 ORDER BY emp_no ASC LIMIT 25;Explanation:
UNIONcombines two distinct query sets and eliminates duplicate records.
Q71. Employees in the Highest-Paying Department⌗
[!question] Problem Statement Find all active employees who work in the department that has the highest average salary.
[!tip] Concepts Tested Subquery with
ORDER BY ... LIMIT 1
[!success]- Reveal SQL Solution
SELECT e.emp_no, CONCAT(e.first_name, ' ', e.last_name) AS full_name, de.dept_no FROM employees e JOIN dept_emp de ON e.emp_no = de.emp_no WHERE de.to_date = '9999-01-01' AND de.dept_no = ( SELECT de2.dept_no FROM dept_emp de2 JOIN salaries s2 ON de2.emp_no = s2.emp_no WHERE de2.to_date = '9999-01-01' AND s2.to_date = '9999-01-01' GROUP BY de2.dept_no ORDER BY AVG(s2.salary) DESC LIMIT 1 ) LIMIT 20;Explanation: Finds the top department ID via a subquery, then filters active employees by that ID.
Q72. Salary Delta from Company Average⌗
[!question] Problem Statement Display each active employee’s salary alongside the exact numerical difference from the overall company average.
[!tip] Concepts Tested Scalar Subquery in
SELECT
[!success]- Reveal SQL Solution
SELECT emp_no, salary, ROUND((SELECT AVG(salary) FROM salaries WHERE to_date = '9999-01-01'), 2) AS company_avg, ROUND(salary - (SELECT AVG(salary) FROM salaries WHERE to_date = '9999-01-01'), 2) AS variance_from_avg FROM salaries WHERE to_date = '9999-01-01' LIMIT 20;Explanation: Evaluates a scalar aggregate subquery directly within the
SELECTcolumn list.
Q73. Employees Who Experienced a Salary Reduction⌗
[!question] Problem Statement Identify employees who had a salary decrease from one pay record to the next.
[!tip] Concepts Tested Correlated Subquery or Self-Join
[!success]- Reveal SQL Solution
SELECT DISTINCT s1.emp_no FROM salaries s1 JOIN salaries s2 ON s1.emp_no = s2.emp_no AND s1.to_date = s2.from_date WHERE s2.salary < s1.salary LIMIT 20;Explanation: Matches consecutive salary intervals (
s1.to_date = s2.from_date) and checks if the new salarys2is strictly lower thans1.
Q74. Employees Hired After Their Current Manager⌗
[!question] Problem Statement Find active employees who were hired on a date after their department’s current manager was hired.
[!tip] Concepts Tested Multi-table comparison
[!success]- Reveal SQL Solution
SELECT e.emp_no, CONCAT(e.first_name, ' ', e.last_name) AS employee, e.hire_date AS employee_hired, CONCAT(m.first_name, ' ', m.last_name) AS manager, m.hire_date AS manager_hired FROM dept_emp de JOIN employees e ON de.emp_no = e.emp_no JOIN dept_manager dm ON de.dept_no = dm.dept_no AND dm.to_date = '9999-01-01' JOIN employees m ON dm.emp_no = m.emp_no WHERE de.to_date = '9999-01-01' AND e.hire_date > m.hire_date LIMIT 20;Explanation: Compares the
hire_dateattributes between employee and department manager.
Q75. Departments Where Every Employee Earns Over $40k⌗
[!question] Problem Statement Find all department IDs where every single active employee earns over $40,000 (no one earns <= $40,000).
[!tip] Concepts Tested
NOT EXISTSDouble Negative
[!success]- Reveal SQL Solution
SELECT d.dept_no, d.dept_name FROM departments d WHERE NOT EXISTS ( SELECT 1 FROM dept_emp de JOIN salaries s ON de.emp_no = s.emp_no WHERE de.dept_no = d.dept_no AND de.to_date = '9999-01-01' AND s.to_date = '9999-01-01' AND s.salary <= 40000 );Explanation: Universal quantification in SQL (‘all X satisfy Y’) is expressed via universal negative (’there exists no X that violates Y’).
🟢 Part 6: Window Functions & Analytical SQL⌗
Focus: ROW_NUMBER, DENSE_RANK, LAG, LEAD, NTILE, and running aggregates.
Q76. Department Salary Ranking (DENSE_RANK)⌗
[!question] Problem Statement Rank active employees by salary within their respective department without gaps for ties.
[!tip] Concepts Tested
DENSE_RANK() OVER (PARTITION BY ... ORDER BY ...)
[!success]- Reveal SQL Solution
SELECT de.dept_no, s.emp_no, s.salary, DENSE_RANK() OVER ( PARTITION BY de.dept_no ORDER BY s.salary DESC ) AS department_salary_rank FROM dept_emp de JOIN salaries s ON de.emp_no = s.emp_no WHERE de.to_date = '9999-01-01' AND s.to_date = '9999-01-01' LIMIT 25;Explanation:
DENSE_RANK()assigns ranks 1, 2, 2, 3 without skipping rank numbers when ties occur.
Q77. Top 3 Highest-Paid Employees per Department⌗
[!question] Problem Statement Retrieve the top 3 highest-earning employees in every department.
[!tip] Concepts Tested CTE +
ROW_NUMBER()Window Function
[!success]- Reveal SQL Solution
WITH DepartmentRankings AS ( SELECT de.dept_no, d.dept_name, e.emp_no, CONCAT(e.first_name, ' ', e.last_name) AS full_name, s.salary, ROW_NUMBER() OVER ( PARTITION BY de.dept_no ORDER BY s.salary DESC ) AS rank_in_dept FROM dept_emp de JOIN departments d ON de.dept_no = d.dept_no JOIN employees e ON de.emp_no = e.emp_no JOIN salaries s ON de.emp_no = s.emp_no WHERE de.to_date = '9999-01-01' AND s.to_date = '9999-01-01' ) SELECT dept_no, dept_name, full_name, salary, rank_in_dept FROM DepartmentRankings WHERE rank_in_dept <= 3 ORDER BY dept_no, rank_in_dept;Explanation: Classic SQL interview archetype: Partition by group, order by metric, filter
rank <= Nvia CTE.
Q78. Running Total (Cumulative Sum) of Payroll⌗
[!question] Problem Statement Calculate the running cumulative sum of active payroll ordered by employee ID.
[!tip] Concepts Tested
SUM() OVER (ORDER BY ...)
[!success]- Reveal SQL Solution
SELECT emp_no, salary, SUM(salary) OVER ( ORDER BY emp_no ASC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS cumulative_payroll FROM salaries WHERE to_date = '9999-01-01' LIMIT 20;Explanation: Computes cumulative rolling sum across rows from the start of the partition through the current row.
Q79. Salary Raise Percentage per Employee (LAG)⌗
[!question] Problem Statement For each employee, display their current salary, previous salary, and the percentage raise received.
[!tip] Concepts Tested
LAG() OVER (PARTITION BY ... ORDER BY ...)
[!success]- Reveal SQL Solution
WITH SalaryHistory AS ( SELECT emp_no, salary, from_date, LAG(salary, 1) OVER ( PARTITION BY emp_no ORDER BY from_date ASC ) AS prev_salary FROM salaries ) SELECT emp_no, from_date, prev_salary, salary AS current_term_salary, ROUND(((salary - prev_salary) / prev_salary) * 100, 2) AS percentage_increase FROM SalaryHistory WHERE prev_salary IS NOT NULL LIMIT 20;Explanation:
LAG(col, 1)accesses data from the previous row within the partition.
Q80. Look Ahead to Next Salary (LEAD)⌗
[!question] Problem Statement Using
LEAD(), compare each historical salary with the next one to flag any pay reductions.
[!tip] Concepts Tested
LEAD() OVER (...)
[!success]- Reveal SQL Solution
WITH NextSalaryCTE AS ( SELECT emp_no, salary, from_date, LEAD(salary, 1) OVER ( PARTITION BY emp_no ORDER BY from_date ASC ) AS next_salary FROM salaries ) SELECT emp_no, from_date, salary, next_salary, (next_salary - salary) AS change_amount FROM NextSalaryCTE WHERE next_salary IS NOT NULL AND next_salary < salary LIMIT 20;Explanation:
LEAD(col, 1)inspects the next sequential row in the window.
Q81. Salary Quartiles per Department (NTILE)⌗
[!question] Problem Statement Divide employees into 4 compensation quartiles (1=Lowest, 4=Highest) within their respective department.
[!tip] Concepts Tested
NTILE(4) OVER (PARTITION BY ... ORDER BY ...)
[!success]- Reveal SQL Solution
SELECT de.dept_no, s.emp_no, s.salary, NTILE(4) OVER ( PARTITION BY de.dept_no ORDER BY s.salary ASC ) AS salary_quartile FROM dept_emp de JOIN salaries s ON de.emp_no = s.emp_no WHERE de.to_date = '9999-01-01' AND s.to_date = '9999-01-01' LIMIT 25;Explanation:
NTILE(N)divides rows in each department partition into $N$ equal-sized buckets.
Q82. Max Department Salary on Every Employee Row⌗
[!question] Problem Statement Display each active employee’s salary alongside their department’s maximum salary without using
GROUP BY.
[!tip] Concepts Tested
MAX() OVER (PARTITION BY ...)
[!success]- Reveal SQL Solution
SELECT de.dept_no, s.emp_no, s.salary, MAX(s.salary) OVER (PARTITION BY de.dept_no) AS dept_max_salary, (MAX(s.salary) OVER (PARTITION BY de.dept_no) - s.salary) AS gap_to_top FROM dept_emp de JOIN salaries s ON de.emp_no = s.emp_no WHERE de.to_date = '9999-01-01' AND s.to_date = '9999-01-01' LIMIT 25;Explanation: Window aggregates compute summary metrics without collapsing individual rows.
Q83. 3-Term Moving Average Salary⌗
[!question] Problem Statement Calculate the 3-term moving average salary for each employee across their compensation history.
[!tip] Concepts Tested
AVG() OVER (PARTITION BY ... ROWS BETWEEN ...)
[!success]- Reveal SQL Solution
SELECT emp_no, from_date, salary, ROUND(AVG(salary) OVER ( PARTITION BY emp_no ORDER BY from_date ASC ROWS BETWEEN 2 PRECEDING AND CURRENT ROW ), 2) AS moving_avg_3_terms FROM salaries LIMIT 25;Explanation:
ROWS BETWEEN 2 PRECEDING AND CURRENT ROWspecifies an exact 3-row moving window frame.
Q84. Gap to Top Earner (FIRST_VALUE)⌗
[!question] Problem Statement Compute the dollar gap between each employee’s salary and the highest earner in their department using
FIRST_VALUE().
[!tip] Concepts Tested
FIRST_VALUE() OVER (PARTITION BY ... ORDER BY ...)
[!success]- Reveal SQL Solution
SELECT de.dept_no, s.emp_no, s.salary, FIRST_VALUE(s.salary) OVER ( PARTITION BY de.dept_no ORDER BY s.salary DESC ) AS top_dept_salary, (FIRST_VALUE(s.salary) OVER ( PARTITION BY de.dept_no ORDER BY s.salary DESC ) - s.salary) AS deficit_to_top FROM dept_emp de JOIN salaries s ON de.emp_no = s.emp_no WHERE de.to_date = '9999-01-01' AND s.to_date = '9999-01-01' LIMIT 25;Explanation:
FIRST_VALUE()grabs the leading value in the sorted window partition.
Q85. Top 5th Percentile Earners (PERCENT_RANK)⌗
[!question] Problem Statement Identify employees who rank in the top 5% of earners in their department (
PERCENT_RANK >= 0.95).
[!tip] Concepts Tested
PERCENT_RANK() OVER (...)
[!success]- Reveal SQL Solution
WITH DepartmentPercentiles AS ( SELECT de.dept_no, s.emp_no, s.salary, PERCENT_RANK() OVER ( PARTITION BY de.dept_no ORDER BY s.salary ASC ) AS pct_rank FROM dept_emp de JOIN salaries s ON de.emp_no = s.emp_no WHERE de.to_date = '9999-01-01' AND s.to_date = '9999-01-01' ) SELECT dept_no, emp_no, salary, ROUND(pct_rank, 4) AS percentile FROM DepartmentPercentiles WHERE pct_rank >= 0.95 ORDER BY dept_no, salary DESC LIMIT 20;Explanation:
PERCENT_RANK()calculates the relative rank between 0.0 and 1.0.
Q86. Date When Peak Historical Salary Was Achieved⌗
[!question] Problem Statement For each employee, identify the exact date when they achieved their highest career salary.
[!tip] Concepts Tested Window Ranking
ROW_NUMBER()over partition
[!success]- Reveal SQL Solution
WITH RankedSalaries AS ( SELECT emp_no, salary, from_date, ROW_NUMBER() OVER ( PARTITION BY emp_no ORDER BY salary DESC, from_date ASC ) AS rn FROM salaries ) SELECT emp_no, salary AS peak_salary, from_date AS peak_date FROM RankedSalaries WHERE rn = 1 LIMIT 20;Explanation: Orders compensation in descending order per employee to isolate their personal career peak.
Q87. Median Salary Earner per Department⌗
[!question] Problem Statement Find the employee whose salary represents the exact median within their department.
[!tip] Concepts Tested Window ranking comparison against
COUNT(*) / 2
[!success]- Reveal SQL Solution
WITH DeptCounts AS ( SELECT de.dept_no, s.emp_no, s.salary, ROW_NUMBER() OVER (PARTITION BY de.dept_no ORDER BY s.salary ASC) AS rnk, COUNT(*) OVER (PARTITION BY de.dept_no) AS total_count FROM dept_emp de JOIN salaries s ON de.emp_no = s.emp_no WHERE de.to_date = '9999-01-01' AND s.to_date = '9999-01-01' ) SELECT dept_no, emp_no, salary AS median_salary FROM DeptCounts WHERE rnk = FLOOR((total_count + 1) / 2);Explanation: Finds the middle row index
FLOOR((total_count + 1) / 2)in the sorted salary partition.
Q88. Sequential Career Promotion Numbering⌗
[!question] Problem Statement Assign a sequential career promotion number (1, 2, 3…) to every title change an employee has experienced.
[!tip] Concepts Tested
ROW_NUMBER() OVER (PARTITION BY ... ORDER BY ...)
[!success]- Reveal SQL Solution
SELECT emp_no, title, from_date, to_date, ROW_NUMBER() OVER ( PARTITION BY emp_no ORDER BY from_date ASC ) AS career_stage_number FROM titles LIMIT 25;Explanation: Indexes consecutive career progression stages chronologically.
Q89. Detect Overlapping Date Ranges in Salaries⌗
[!question] Problem Statement Identify any data anomalies where an employee’s salary
from_dateoccurs before the previous record’sto_date.
[!tip] Concepts Tested
LAG()on date columns
[!success]- Reveal SQL Solution
WITH ConsecutiveSalaries AS ( SELECT emp_no, from_date, to_date, LAG(to_date, 1) OVER ( PARTITION BY emp_no ORDER BY from_date ASC ) AS prev_to_date FROM salaries ) SELECT emp_no, from_date, to_date, prev_to_date FROM ConsecutiveSalaries WHERE prev_to_date IS NOT NULL AND from_date < prev_to_date;Explanation: Detects invalid overlapping temporal intervals.
Q90. Top 75th Percentile Earners Across the Whole Company⌗
[!question] Problem Statement Identify active employees earning strictly in the top 25% of the overall company (
CUME_DIST > 0.75).
[!tip] Concepts Tested
CUME_DIST() OVER (...)
[!success]- Reveal SQL Solution
WITH OverallPercentiles AS ( SELECT emp_no, salary, CUME_DIST() OVER (ORDER BY salary ASC) AS cumulative_dist FROM salaries WHERE to_date = '9999-01-01' ) SELECT emp_no, salary, ROUND(cumulative_dist, 4) AS dist FROM OverallPercentiles WHERE cumulative_dist > 0.75 ORDER BY salary ASC LIMIT 20;Explanation:
CUME_DIST()evaluates cumulative distribution across the entire enterprise.
🟢 Part 7: Advanced Business Logic & Edge Cases⌗
Focus: Turnover metrics, recursive series, Gaps & Islands, pay inversion, and audit queries.
Q91. Department Turnover Rate⌗
[!question] Problem Statement Calculate the employee turnover percentage per department (departed employees vs total ever assigned).
[!tip] Concepts Tested Conditional Aggregation with CTE
[!success]- Reveal SQL Solution
WITH DepartmentTurnover AS ( SELECT dept_no, COUNT(*) AS total_ever_assigned, SUM(CASE WHEN to_date <> '9999-01-01' THEN 1 ELSE 0 END) AS departed_count FROM dept_emp GROUP BY dept_no ) SELECT d.dept_no, d.dept_name, dt.total_ever_assigned, dt.departed_count, ROUND((dt.departed_count * 100.0 / dt.total_ever_assigned), 2) AS turnover_percentage FROM DepartmentTurnover dt JOIN departments d ON dt.dept_no = d.dept_no ORDER BY turnover_percentage DESC;Explanation: Flags departed personnel (
to_date <> '9999-01-01') and computes attrition percentage.
Q92. Continuous Calendar Series of Hires (Recursive CTE)⌗
[!question] Problem Statement Generate a complete calendar series of years from 1985 to 2000 and count employee hires, showing 0 for empty years.
[!tip] Concepts Tested
WITH RECURSIVE,LEFT JOIN,COALESCE()
[!success]- Reveal SQL Solution
WITH RECURSIVE YearRange AS ( SELECT 1985 AS cal_year UNION ALL SELECT cal_year + 1 FROM YearRange WHERE cal_year < 2000 ) SELECT yr.cal_year, COUNT(e.emp_no) AS total_hires FROM YearRange yr LEFT JOIN employees e ON yr.cal_year = YEAR(e.hire_date) GROUP BY yr.cal_year ORDER BY yr.cal_year ASC;Explanation: Generates a synthetic timeline table on the fly to avoid omitting missing zero-count periods.
Q93. Average Promotion Duration: Engineer to Senior Engineer⌗
[!question] Problem Statement Calculate the average duration (in years) it takes for an employee to get promoted from ‘Engineer’ to ‘Senior Engineer’.
[!tip] Concepts Tested Self-join on
titleswithTIMESTAMPDIFF()
[!success]- Reveal SQL Solution
WITH Promotions AS ( SELECT t1.emp_no, t1.from_date AS engineer_start, t2.from_date AS senior_start, TIMESTAMPDIFF(MONTH, t1.from_date, t2.from_date) / 12.0 AS years_to_promo FROM titles t1 JOIN titles t2 ON t1.emp_no = t2.emp_no AND t1.title = 'Engineer' AND t2.title = 'Senior Engineer' AND t1.from_date < t2.from_date ) SELECT ROUND(AVG(years_to_promo), 2) AS avg_years_to_promotion, MIN(years_to_promo) AS fastest_promotion_years, MAX(years_to_promo) AS slowest_promotion_years FROM Promotions;Explanation: Calculates the promotion timeline between two specific sequential job milestones.
Q94. Manager Presiding Over the Largest Department Payroll⌗
[!question] Problem Statement Identify which manager managed the largest total current department payroll.
[!tip] Concepts Tested Multi-table
JOIN,SUM(),ORDER BY DESC LIMIT 1
[!success]- Reveal SQL Solution
SELECT dm.dept_no, d.dept_name, dm.emp_no AS manager_emp_no, CONCAT(e.first_name, ' ', e.last_name) AS manager_name, SUM(s.salary) AS managed_active_payroll FROM dept_manager dm JOIN departments d ON dm.dept_no = d.dept_no JOIN employees e ON dm.emp_no = e.emp_no JOIN dept_emp de ON dm.dept_no = de.dept_no JOIN salaries s ON de.emp_no = s.emp_no WHERE dm.to_date = '9999-01-01' AND de.to_date = '9999-01-01' AND s.to_date = '9999-01-01' GROUP BY dm.dept_no, d.dept_name, dm.emp_no, manager_name ORDER BY managed_active_payroll DESC LIMIT 1;Explanation: Aggregates total staff salaries subordinate to each active department manager.
Q95. Gaps and Islands: Continuous Title Tenures⌗
[!question] Problem Statement Detect distinct continuous islands of consecutive title periods for employees.
[!tip] Concepts Tested
LAG(),SUM() OVER ()Gaps and Islands pattern
[!success]- Reveal SQL Solution
WITH Step1 AS ( SELECT emp_no, title, from_date, to_date, CASE WHEN LAG(to_date) OVER (PARTITION BY emp_no, title ORDER BY from_date) = from_date THEN 0 ELSE 1 END AS is_new_island FROM titles ), Step2 AS ( SELECT emp_no, title, from_date, to_date, SUM(is_new_island) OVER (PARTITION BY emp_no, title ORDER BY from_date) AS island_id FROM Step1 ) SELECT emp_no, title, MIN(from_date) AS consolidated_start, MAX(to_date) AS consolidated_end FROM Step2 GROUP BY emp_no, title, island_id LIMIT 20;Explanation: Standard Gaps & Islands solution: identifies continuity breaks with
LAGand groups contiguous date blocks with a cumulative sum.
Q96. Salary Inversion Detection⌗
[!question] Problem Statement Find active employees who earn less than a peer in the same department who was hired after them.
[!tip] Concepts Tested Self-Join comparing tenure vs salary
[!success]- Reveal SQL Solution
SELECT e1.emp_no AS senior_employee, e1.hire_date AS senior_hire_date, s1.salary AS senior_salary, e2.emp_no AS junior_employee, e2.hire_date AS junior_hire_date, s2.salary AS junior_salary, de1.dept_no FROM dept_emp de1 JOIN dept_emp de2 ON de1.dept_no = de2.dept_no JOIN employees e1 ON de1.emp_no = e1.emp_no JOIN employees e2 ON de2.emp_no = e2.emp_no JOIN salaries s1 ON e1.emp_no = s1.emp_no JOIN salaries s2 ON e2.emp_no = s2.emp_no WHERE de1.to_date = '9999-01-01' AND de2.to_date = '9999-01-01' AND s1.to_date = '9999-01-01' AND s2.to_date = '9999-01-01' AND e1.hire_date < e2.hire_date AND s1.salary < s2.salary LIMIT 20;Explanation: Identifies organizational pay inversion where longer-tenured employees earn less than newer hires in the same department.
Q97. Department-by-Title Pivot Matrix⌗
[!question] Problem Statement Pivot active employee counts by title across major departments into a cross-tabulated matrix.
[!tip] Concepts Tested Conditional Aggregation (
CASE WHEN ...)
[!success]- Reveal SQL Solution
SELECT d.dept_name, SUM(CASE WHEN t.title = 'Senior Engineer' THEN 1 ELSE 0 END) AS sr_engineers, SUM(CASE WHEN t.title = 'Engineer' THEN 1 ELSE 0 END) AS engineers, SUM(CASE WHEN t.title = 'Senior Staff' THEN 1 ELSE 0 END) AS sr_staff, SUM(CASE WHEN t.title = 'Staff' THEN 1 ELSE 0 END) AS staff, SUM(CASE WHEN t.title = 'Technique Leader' THEN 1 ELSE 0 END) AS tech_leads FROM departments d JOIN dept_emp de ON d.dept_no = de.dept_no JOIN titles t ON de.emp_no = t.emp_no WHERE de.to_date = '9999-01-01' AND t.to_date = '9999-01-01' GROUP BY d.dept_name ORDER BY d.dept_name ASC;Explanation: Standard SQL pivot technique converting row values into dedicated summary columns.
Q98. Female Representation in Department Leadership⌗
[!question] Problem Statement Calculate the historical percentage of female managers for each department.
[!tip] Concepts Tested Conditional Aggregation on
dept_manager
[!success]- Reveal SQL Solution
SELECT d.dept_no, d.dept_name, COUNT(*) AS total_managers_history, SUM(CASE WHEN e.gender = 'F' THEN 1 ELSE 0 END) AS female_managers, ROUND(SUM(CASE WHEN e.gender = 'F' THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2) AS female_leadership_pct FROM departments d JOIN dept_manager dm ON d.dept_no = dm.dept_no JOIN employees e ON dm.emp_no = e.emp_no GROUP BY d.dept_no, d.dept_name ORDER BY female_leadership_pct DESC;Explanation: Analyzes gender representation in departmental leadership appointments.
Q99. Year-over-Year (YoY) Total Payroll Growth⌗
[!question] Problem Statement Calculate the Year-over-Year (YoY) percentage growth in total annual payroll expenditure.
[!tip] Concepts Tested
LAG(), Window Function on Aggregated Annual Data
[!success]- Reveal SQL Solution
WITH AnnualPayroll AS ( SELECT YEAR(from_date) AS payroll_year, SUM(salary) AS total_payroll FROM salaries WHERE YEAR(from_date) BETWEEN 1986 AND 2000 GROUP BY payroll_year ), PayrollGrowth AS ( SELECT payroll_year, total_payroll, LAG(total_payroll, 1) OVER (ORDER BY payroll_year ASC) AS prior_year_payroll FROM AnnualPayroll ) SELECT payroll_year, total_payroll, prior_year_payroll, ROUND(((total_payroll - prior_year_payroll) / prior_year_payroll) * 100, 2) AS yoy_growth_percentage FROM PayrollGrowth WHERE prior_year_payroll IS NOT NULL ORDER BY payroll_year ASC;Explanation: Computes consecutive annual financial deltas and YoY percentage expansion.
Q100. Detect Overlapping Department Tenures⌗
[!question] Problem Statement Write an audit query to detect any employee who has simultaneous overlapping
from_dateandto_dateintervals indept_emp.
[!tip] Concepts Tested Self-Join Interval Intersection
[!success]- Reveal SQL Solution
SELECT de1.emp_no, de1.dept_no AS dept_1, de1.from_date AS start_1, de1.to_date AS end_1, de2.dept_no AS dept_2, de2.from_date AS start_2, de2.to_date AS end_2 FROM dept_emp de1 JOIN dept_emp de2 ON de1.emp_no = de2.emp_no AND de1.from_date < de2.from_date WHERE de1.to_date > de2.from_date LIMIT 20;Explanation: Essential data engineering and QA query that flags conflicting temporal assignments (
start_1 < start_2 AND end_1 > start_2).