Questions and Answers (Basic to
Advanced)
1. 1. Write a query to fetch all records from the employees table.
SELECT * FROM employees;
2. 2. Write a query to retrieve only the first_name and last_name of all employees.
SELECT first_name, last_name FROM employees;
3. 3. Write a query to fetch employees whose salary is greater than 50,000.
SELECT * FROM employees WHERE salary > 50000;
4. 4. Write a query to retrieve all employees sorted by salary in descending order.
SELECT * FROM employees ORDER BY salary DESC;
5. 5. Write a query to get unique department names from the employees table.
SELECT DISTINCT department FROM employees;
6. 6. Write a query to find all employees who work in the departments 'HR' or 'IT'.
SELECT * FROM employees WHERE department IN ('HR', 'IT');
7. 7. Write a query to fetch employees whose salary is between 40,000 and 80,000.
SELECT * FROM employees WHERE salary BETWEEN 40000 AND
80000;
8. 8. Write a query to find employees whose first name starts with the letter 'A'.
SELECT * FROM employees WHERE first_name LIKE 'A%';
9. 9. Write a query to count the number of employees in each department.
SELECT department, COUNT(*) FROM employees GROUP BY
department;
10. 10. Write a query to find the average salary of employees department-wise.
SELECT department, AVG(salary) FROM employees GROUP BY
department;
11. 11. Write a query to find departments having more than 5 employees.
SELECT department, COUNT(*) FROM employees GROUP BY
department HAVING COUNT(*) > 5;
12. 12. Write a query to find the maximum, minimum, and total salary of employees.
SELECT MAX(salary), MIN(salary), SUM(salary) FROM employees;
13. 13. Write a query to display employee names along with their department names using
INNER JOIN.
SELECT e.first_name, d.department_name FROM employees e INNER
JOIN departments d ON e.dept_id = d.id;
14. 14. Write a query to display all employees and their departments using LEFT JOIN.
SELECT e.first_name, d.department_name FROM employees e LEFT
JOIN departments d ON e.dept_id = d.id;
15. 15. Write a query to list all departments and the employees working in them using
RIGHT JOIN.
SELECT e.first_name, d.department_name FROM employees e RIGHT
JOIN departments d ON e.dept_id = d.id;
16. 16. Write a query to show all employees and all departments using FULL OUTER JOIN.
SELECT e.first_name, d.department_name FROM employees e FULL
OUTER JOIN departments d ON e.dept_id = d.id;
17. 17. Write an INSERT query to add a new employee into the employees table.
INSERT INTO employees (first_name, last_name, dept_id, salary)
VALUES ('John', 'Doe', 3, 60000);
18. 18. Write an UPDATE query to increase the salary of an employee with employee_id =
101 to 70,000.
UPDATE employees SET salary = 70000 WHERE employee_id = 101;
19. 19. Write a DELETE query to remove the employee with employee_id = 101 from the
table.
DELETE FROM employees WHERE employee_id = 101;
20. 20. Write a CREATE TABLE query for a table named employees.
CREATE TABLE employees (
employee_id INT PRIMARY KEY,
first_name VARCHAR(50),
last_name VARCHAR(50),
dept_id INT,
salary DECIMAL(10,2)
);
21. 21. Write an ALTER TABLE query to add a new column hire_date of type DATE.
ALTER TABLE employees ADD hire_date DATE;
22. 22. Write an ALTER TABLE query to modify the salary column.
ALTER TABLE employees MODIFY salary DECIMAL(12,2);
23. 23. Write an ALTER TABLE query to drop the hire_date column.
ALTER TABLE employees DROP COLUMN hire_date;
24. 24. Write a DROP TABLE query to delete the employees table.
DROP TABLE employees;
25. 25. Write a query to find all employees whose salary is greater than the average salary.
SELECT * FROM employees WHERE salary > (SELECT AVG(salary)
FROM employees);
26. 26. Write a query to find the departments that have more than 2 employees using a
subquery.
SELECT department FROM employees GROUP BY department
HAVING COUNT(*) > 2;
27. 27. Write a query to find employees who earn the highest salary in their department.
SELECT * FROM employees e WHERE salary = (SELECT MAX(salary)
FROM employees WHERE dept_id = e.dept_id);
28. 28. Write a query to display each employee’s salary rank within their department using
RANK().
SELECT employee_id, first_name, department, salary, RANK() OVER
(PARTITION BY department ORDER BY salary DESC) AS dept_rank
FROM employees;
29. 29. Write a query to assign a unique row number using ROW_NUMBER().
SELECT employee_id, ROW_NUMBER() OVER (PARTITION BY
department ORDER BY salary DESC) AS row_num FROM employees;
30. 30. Write a query to calculate cumulative salary using SUM() OVER().
SELECT employee_id, salary, SUM(salary) OVER (ORDER BY salary)
AS cumulative_salary FROM employees;
31. 31. Write a query using CTE to find employees earning more than 100,000 and filter for
Engineering.
WITH HighEarners AS (
SELECT * FROM employees WHERE salary > 100000
)
SELECT * FROM HighEarners WHERE department = 'Engineering';
32. 32. Write a query to classify employees into salary bands using CASE WHEN.
SELECT first_name, salary,
CASE
WHEN salary < 50000 THEN 'Low'
WHEN salary BETWEEN 50000 AND 100000 THEN 'Medium'
ELSE 'High'
END AS salary_band
FROM employees;
33. 33. Write a query to find duplicate employee first names.
SELECT first_name, COUNT(*) FROM employees GROUP BY first_name
HAVING COUNT(*) > 1;
34. 34. Write a query to find the 3rd highest salary.
SELECT salary FROM (
SELECT salary, DENSE_RANK() OVER (ORDER BY salary DESC) AS
rnk FROM employees
) AS ranked WHERE rnk = 3;
35. 35. Write a CREATE TABLE statement for departments with constraints.
CREATE TABLE departments (
dept_id INT PRIMARY KEY,
dept_name VARCHAR(50) UNIQUE,
location VARCHAR(50) NOT NULL
);
36. 36. Write an ALTER TABLE to add a foreign key.
ALTER TABLE employees ADD CONSTRAINT fk_dept FOREIGN KEY
(dept_id) REFERENCES departments(dept_id);
37. 37. Write a query to find the top 3 earners from each department.
SELECT * FROM (
SELECT *, DENSE_RANK() OVER (PARTITION BY dept_id ORDER BY
salary DESC) AS rnk FROM employees
) ranked WHERE rnk <= 3;
38. 38. Write a query to find the employee(s) with the second highest salary.
SELECT * FROM employees WHERE salary = (
SELECT DISTINCT salary FROM employees ORDER BY salary DESC
LIMIT 1 OFFSET 1
);
39. 39. Write a query to find employees who joined in the last 6 months.
SELECT * FROM employees WHERE hire_date >= CURRENT_DATE -
INTERVAL '6 months';
40. 40. Write a query to list all employees who do not belong to any department.
SELECT * FROM employees WHERE dept_id IS NULL;
41. 41. Write a query to find the total salary paid in each department (including empty
depts).
SELECT d.department_name, COALESCE(SUM(e.salary), 0) AS
total_salary
FROM departments d
LEFT JOIN employees e ON d.dept_id = e.dept_id
GROUP BY d.department_name;
42. 42. Write a query to get the department with the highest average salary.
SELECT department FROM employees GROUP BY department ORDER
BY AVG(salary) DESC LIMIT 1;
43. 43. Write a query to list managers and their number of reportees.
SELECT manager_id, COUNT(*) AS reportees FROM employees
GROUP BY manager_id;
44. 44. Write a query to pivot employee gender counts.
SELECT
COUNT(CASE WHEN gender = 'Male' THEN 1 END) AS male_count,
COUNT(CASE WHEN gender = 'Female' THEN 1 END) AS
female_count
FROM employees;
45. 45. Write a query to list all the tables in the current database.
SHOW TABLES;
46. 46. Write a query to describe the structure of the employees table.
DESCRIBE employees;
47. 47. Write a query to find the data type of each column in a table.
SELECT column_name, data_type FROM
information_schema.columns WHERE table_name = 'employees';
1. Get the employee with the highest salary in each department
Answer:
SELECT * FROM employees e
WHERE salary = (
SELECT MAX(salary) FROM employees
WHERE dept_id = e.dept_id
);
2. Find the top 3 earners per department using a window function
Answer:
SELECT * FROM (
SELECT *, DENSE_RANK() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS rnk
FROM employees
) AS ranked
WHERE rnk <= 3;
3. Write a query to find the Nth highest salary in a table without using LIMIT or TOP
Answer:
SELECT salary FROM (
SELECT salary, DENSE_RANK() OVER (ORDER BY salary DESC) AS rnk
FROM employees
) AS ranked
WHERE rnk = N;
4. Write a query to delete all duplicate records from a table while keeping only one
occurrence
Answer:
DELETE FROM employees
WHERE id NOT IN (
SELECT MIN(id)
FROM employees
GROUP BY first_name, last_name, dept_id, salary
);
5. Write a query to delete only the first duplicate (based on row ID or order)
Answer:
DELETE FROM employees
WHERE id IN (
SELECT id FROM (
SELECT id, ROW_NUMBER() OVER (PARTITION BY first_name, last_name, dept_id, salary
ORDER BY id) AS rn
FROM employees
) AS temp
WHERE rn = 1
);
6. Find employees who have the same salary within each department
Answer:
SELECT * FROM employees e1
JOIN employees e2 ON e1.dept_id = e2.dept_id AND e1.salary = e2.salary AND e1.id <> e2.id;
7. Find the median salary from the employees table
Answer:
SELECT AVG(salary) AS median FROM (
SELECT salary FROM employees ORDER BY salary
LIMIT 1 OFFSET (SELECT COUNT(*)/2 FROM employees)
) AS sub;
8. Find employees who earn more than their department’s average salary
Answer:
SELECT * FROM employees e
WHERE salary > (
SELECT AVG(salary)
FROM employees
WHERE dept_id = e.dept_id
);
9. Return employees whose salaries are in the top 10 percentile
Answer:
SELECT * FROM (
SELECT *, NTILE(10) OVER (ORDER BY salary DESC) AS decile
FROM employees
) AS top10
WHERE decile = 1;
10. Find employees who do not have a manager (i.e., manager_id is NULL)
Answer:
SELECT * FROM employees
WHERE manager_id IS NULL;
11. Retrieve the department with the most employees
Answer:
SELECT department, COUNT(*) AS emp_count
FROM employees
GROUP BY department
ORDER BY emp_count DESC
LIMIT 1;
12. Departments where average salary is higher than company average
Answer:
SELECT department
FROM employees
GROUP BY department
HAVING AVG(salary) > (SELECT AVG(salary) FROM employees);
13. Number of employees hired each month in the last year
Answer:
SELECT TO_CHAR(hire_date, 'YYYY-MM') AS month, COUNT(*)
FROM employees
WHERE hire_date >= CURRENT_DATE - INTERVAL '1 year'
GROUP BY month;
14. Difference between highest and lowest salary in each department
Answer:
SELECT department, MAX(salary) - MIN(salary) AS salary_diff
FROM employees
GROUP BY department;
15. Count of employees who report to each manager
Answer:
SELECT manager_id, COUNT(*)
FROM employees
GROUP BY manager_id;
16. Employees who joined in the last 90 days
Answer:
SELECT * FROM employees
WHERE hire_date >= CURRENT_DATE - INTERVAL '90 days';
17. Number of days each employee has worked
Answer:
SELECT first_name, last_name, CURRENT_DATE - hire_date AS days_worked
FROM employees;
18. Transpose department names as columns and count employees
Answer:
SELECT
COUNT(*) FILTER (WHERE department = 'HR') AS HR,
COUNT(*) FILTER (WHERE department = 'Sales') AS Sales
FROM employees;
19. Fetch employees with even-numbered IDs
Answer:
SELECT * FROM employees
WHERE MOD(employee_id, 2) = 0;
20. Employees not assigned to any department
Answer:
SELECT * FROM employees
WHERE dept_id IS NULL;
21. Calculate year-over-year employee count change
Answer:
SELECT EXTRACT(YEAR FROM hire_date) AS year, COUNT(*)
FROM employees
GROUP BY year
ORDER BY year;
22. Get the second highest salary per department using DENSE_RANK()
Answer:
SELECT * FROM (
SELECT *, DENSE_RANK() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS rnk
FROM employees
) ranked
WHERE rnk = 2;
23. Find the department that has never hired any employees
Answer:
SELECT d.dept_name
FROM departments d
LEFT JOIN employees e ON d.dept_id = e.dept_id
WHERE e.dept_id IS NULL;
24. List all employees with the same first name but different departments
Answer:
SELECT * FROM employees e1
WHERE EXISTS (
SELECT 1 FROM employees e2
WHERE e1.first_name = e2.first_name AND e1.department <> e2.department AND e1.id <>
e2.id
);
25. Employee pairs with same salary but different departments
Answer:
SELECT e1.*, e2.*
FROM employees e1
JOIN employees e2 ON e1.salary = e2.salary AND e1.dept_id <> e2.dept_id AND e1.id < e2.id;
26. Salary distribution buckets (0–50K, 50K–100K, etc.)
Answer:
SELECT salary,
CASE
WHEN salary < 50000 THEN 'Low'
WHEN salary BETWEEN 50000 AND 100000 THEN 'Medium'
ELSE 'High'
END AS band,
COUNT(*)
FROM employees
GROUP BY salary, band;
27. Departments and average salaries, sorted from highest to lowest
Answer:
SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department
ORDER BY avg_salary DESC;
28. Find gaps in employee IDs (missing sequences)
Answer:
SELECT t1.employee_id + 1 AS missing_id
FROM employees t1
LEFT JOIN employees t2 ON t1.employee_id + 1 = t2.employee_id
WHERE t2.employee_id IS NULL;
29. Cumulative salary expense month-over-month
Answer:
SELECT TO_CHAR(hire_date, 'YYYY-MM') AS month, SUM(salary)
FROM employees
GROUP BY month
ORDER BY month;
30. Employee salary rank across the company
Answer:
SELECT first_name, salary,
RANK() OVER (ORDER BY salary DESC) AS rank
FROM employees;
31. How many employees joined each year for the past 5 years
Answer:
SELECT EXTRACT(YEAR FROM hire_date) AS year, COUNT(*)
FROM employees
WHERE hire_date >= CURRENT_DATE - INTERVAL '5 years'
GROUP BY year
ORDER BY year;
32. Employees earning more than their managers
Answer:
SELECT e1.*
FROM employees e1
JOIN employees e2 ON e1.manager_id = e2.employee_id
WHERE e1.salary > e2.salary;
33. Departments with more than 50% of employees earning above dept avg
Answer:
SELECT dept_id
FROM employees
GROUP BY dept_id
HAVING SUM(CASE WHEN salary > (SELECT AVG(salary) FROM employees WHERE dept_id
= employees.dept_id) THEN 1 ELSE 0 END) > COUNT(*) / 2;
34. Count of employees in each salary band (low, medium, high)
Answer:
SELECT
CASE
WHEN salary < 50000 THEN 'Low'
WHEN salary BETWEEN 50000 AND 100000 THEN 'Medium'
ELSE 'High'
END AS band,
COUNT(*)
FROM employees
GROUP BY band;
35. All departments with employee count (including empty depts)
Answer:
SELECT d.dept_name, COUNT(e.employee_id)
FROM departments d
LEFT JOIN employees e ON d.dept_id = e.dept_id
GROUP BY d.dept_name;
36. Duplicate email addresses in employees table
Answer:
SELECT email, COUNT(*)
FROM employees
GROUP BY email
HAVING COUNT(*) > 1;
37. Latest record for each employee by update timestamp
Answer:
SELECT * FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY employee_id ORDER BY update_time
DESC) AS rn
FROM employee_logs
)t
WHERE rn = 1;
38. Employee with the longest tenure
Answer:
SELECT * FROM employees
ORDER BY hire_date ASC
LIMIT 1;
39. Running total of salary ordered by joining date
Answer:
SELECT hire_date,
SUM(salary) OVER (ORDER BY hire_date) AS running_total
FROM employees
ORDER BY hire_date;
40. Rotate (pivot) table from rows to columns for departments
Answer:
SELECT
MAX(CASE WHEN department = 'HR' THEN 1 END) AS HR,
MAX(CASE WHEN department = 'Sales' THEN 1 END) AS Sales
FROM employees;
41. Return all employees who have more than one manager assigned
Answer:
SELECT employee_id
FROM employee_managers
GROUP BY employee_id
HAVING COUNT(manager_id) > 1;
42. Split comma-separated department values into multiple rows
Answer:
SELECT employee_id, TRIM(value) AS department
FROM employees,
LATERAL UNNEST(string_to_array(departments, ',')) AS value;
43. Get the most frequent job title in the company
Answer:
SELECT job_title, COUNT(*) AS count
FROM employees
GROUP BY job_title
ORDER BY count DESC
LIMIT 1;
44. Find employees who had a salary raise in the past year
Answer:
SELECT * FROM salary_history
WHERE change_date >= CURRENT_DATE - INTERVAL '1 year';
45. Retrieve departments with average salary in the top 3
Answer:
SELECT department
FROM employees
GROUP BY department
ORDER BY AVG(salary) DESC
LIMIT 3;
46. Find employees who share the same first and last name
Answer:
SELECT first_name, last_name, COUNT(*)
FROM employees
GROUP BY first_name, last_name
HAVING COUNT(*) > 1;
47. Calculate average time between hire_date and last_promotion_date
Answer:
SELECT AVG(DATE_PART('day', last_promotion_date - hire_date)) AS avg_days
FROM employees
WHERE last_promotion_date IS NOT NULL;
48. Find the employee with the most number of projects assigned
Answer:
SELECT employee_id, COUNT(project_id) AS total_projects
FROM employee_projects
GROUP BY employee_id
ORDER BY total_projects DESC
LIMIT 1;
49. Check referential integrity violations in a foreign key relationship
Answer:
SELECT * FROM employees
WHERE dept_id NOT IN (
SELECT dept_id FROM departments
);
50. List all employee records changed in the past 30 days (audit log)
Answer:
SELECT * FROM employee_logs
WHERE update_time >= CURRENT_DATE - INTERVAL '30 days';