SQL Final Lab Prep – Joins, Subqueries,
Aggregates, Views, Procedures
1. Joins
INNER JOIN: Employees with their department names
SELECT E.name, D.department_name
FROM employees E
INNER JOIN departments D ON E.department_id = D.department_id;
LEFT JOIN: Employees and their managers (even if no manager assigned)
SELECT E.name AS Employee, M.name AS Manager
FROM employees E
LEFT JOIN employees M ON E.manager_id = M.emp_id;
2. Nested vs Correlated Queries
Nested: Employees in 'Sales' department
SELECT name FROM employees
WHERE department_id = (
SELECT department_id FROM departments WHERE department_name = 'Sales'
);
Correlated: Employees earning more than average salary in their department
SELECT E1.name FROM employees E1
WHERE E1.salary > (
SELECT AVG(E2.salary)
FROM employees E2
WHERE E2.department_id = E1.department_id
);
3. Aggregate Functions
Total number of employees
SELECT COUNT(*) AS total_employees FROM employees;
Average salary by department
SELECT department_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id;
Departments with more than 5 employees
SELECT department_id, COUNT(*) AS count
FROM employees
GROUP BY department_id
HAVING COUNT(*) > 5;
4. Views
Create a view of employee and department name
CREATE VIEW emp_dept_view AS
SELECT E.name, D.department_name
FROM employees E
JOIN departments D ON E.department_id = D.department_id;
Use the view
SELECT * FROM emp_dept_view;
Drop the view
DROP VIEW emp_dept_view;
5. Stored Procedures
Show all employees
DELIMITER //
CREATE PROCEDURE showAllEmployees()
BEGIN
SELECT * FROM employees;
END //
DELIMITER ;
Call procedure
CALL showAllEmployees();
Procedure with input parameter
DELIMITER //
CREATE PROCEDURE getEmployeesByDept(IN deptId INT)
BEGIN
SELECT * FROM employees WHERE department_id = deptId;
END //
DELIMITER ;
Call with parameter
CALL getEmployeesByDept(2);
Procedure with output parameter
DELIMITER //
CREATE PROCEDURE countEmployees(OUT total INT)
BEGIN
SELECT COUNT(*) INTO total FROM employees;
END //
DELIMITER ;
Call and get result
CALL countEmployees(@total);
SELECT @total;
1. Joins – Practice Questions
1. Q1. List all employees along with their department names.
SELECT E.name, D.department_name
FROM employees E
JOIN departments D ON E.department_id = D.department_id;
2. Q2. List all employees and their managers.
SELECT E.name AS Employee, M.name AS Manager
FROM employees E
LEFT JOIN employees M ON E.manager_id = M.emp_id;
3. Q3. List departments and number of employees in each (including those with no
employees).
SELECT D.department_name, COUNT(E.emp_id) AS num_employees
FROM departments D
LEFT JOIN employees E ON D.department_id = E.department_id
GROUP BY D.department_name;
4. Q4. List employees who don’t belong to any department.
SELECT name FROM employees
WHERE department_id IS NULL;
5. Q5. List departments without any employees.
SELECT department_name FROM departments
WHERE department_id NOT IN (SELECT DISTINCT department_id FROM employees);
6. Q6. Find employees who share the same manager.
SELECT E1.name AS Employee1, E2.name AS Employee2, E1.manager_id
FROM employees E1
JOIN employees E2 ON E1.manager_id = E2.manager_id
WHERE E1.emp_id != E2.emp_id;
7. Q7. List all employees along with department and manager names.
SELECT E.name, D.department_name, M.name AS Manager
FROM employees E
LEFT JOIN departments D ON E.department_id = D.department_id
LEFT JOIN employees M ON E.manager_id = M.emp_id;
8. Q8. List employee and department info only for employees who have managers.
SELECT E.name, D.department_name, M.name AS Manager
FROM employees E
JOIN departments D ON E.department_id = D.department_id
JOIN employees M ON E.manager_id = M.emp_id;
9. Q9. List employees and their manager IDs, even if no manager assigned.
SELECT name, manager_id FROM employees;
10. Q10. Show department names along with employee names (if any).
SELECT D.department_name, E.name
FROM departments D
LEFT JOIN employees E ON D.department_id = E.department_id;
2. Nested and Correlated Queries – Practice Questions
11. Q1. Find names of employees who work in the 'HR' department.
SELECT name FROM employees
WHERE department_id = (SELECT department_id FROM departments WHERE
department_name = 'HR');
12. Q2. List employees earning more than the average salary.
SELECT name FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);
13. Q3. Find employees who earn more than the average salary in their department.
SELECT E1.name FROM employees E1
WHERE E1.salary > (SELECT AVG(E2.salary)
FROM employees E2
WHERE E2.department_id = E1.department_id);
14. Q4. List departments where average salary is greater than 50000.
SELECT department_id FROM employees
GROUP BY department_id
HAVING AVG(salary) > 50000;
15. Q5. Find employees in departments with more than 5 employees.
SELECT name FROM employees
WHERE department_id IN (
SELECT department_id FROM employees
GROUP BY department_id
HAVING COUNT(*) > 5);
16. Q6. Get employee names who work in a department with ID in (1,2).
SELECT name FROM employees WHERE department_id IN (1, 2);
17. Q7. List employees with salary higher than anyone in department 3.
SELECT name FROM employees
WHERE salary > ALL (
SELECT salary FROM employees WHERE department_id = 3);
18. Q8. Find employees who earn the highest salary in their department.
SELECT name FROM employees E1
WHERE salary = (SELECT MAX(salary)
FROM employees E2
WHERE E2.department_id = E1.department_id);
19. Q9. Get department names with at least one employee having salary > 60000.
SELECT DISTINCT D.department_name
FROM departments D
WHERE D.department_id IN (
SELECT department_id FROM employees WHERE salary > 60000);
20. Q10. Find employee names who work in departments that have 'e' in their name.
SELECT name FROM employees
WHERE department_id IN (
SELECT department_id FROM departments WHERE department_name LIKE '%e%');
3. Aggregate Functions – Practice Questions
21. Q1. Count total number of employees.
SELECT COUNT(*) FROM employees;
22. Q2. Find the average salary of all employees.
SELECT AVG(salary) FROM employees;
23. Q3. Find the highest salary.
SELECT MAX(salary) FROM employees;
24. Q4. Find the lowest salary.
SELECT MIN(salary) FROM employees;
25. Q5. Count the number of employees in each department.
SELECT department_id, COUNT(*)
FROM employees
GROUP BY department_id;
26. Q6. Find the average salary per department.
SELECT department_id, AVG(salary)
FROM employees
GROUP BY department_id;
27. Q7. Find departments with more than 10 employees.
SELECT department_id, COUNT(*)
FROM employees
GROUP BY department_id
HAVING COUNT(*) > 10;
28. Q8. Find total salary paid to each department.
SELECT department_id, SUM(salary)
FROM employees
GROUP BY department_id;
29. Q9. Find the number of managers (distinct manager IDs).
SELECT COUNT(DISTINCT manager_id) FROM employees;
30. Q10. List departments with average salary above 60000.
SELECT department_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id
HAVING AVG(salary) > 60000;
4. Views – Practice Questions
31. Q1. Create a view of employee names and their department names.
CREATE VIEW emp_dept_view AS
SELECT E.name, D.department_name
FROM employees E
JOIN departments D ON E.department_id = D.department_id;
32. Q2. Select all data from the view.
SELECT * FROM emp_dept_view;
33. Q3. Drop the view.
DROP VIEW emp_dept_view;
34. Q4. Create a view with employees earning more than 50000.
CREATE VIEW high_salary_emps AS
SELECT * FROM employees WHERE salary > 50000;
35. Q5. Create a view showing average salary per department.
CREATE VIEW avg_salary_view AS
SELECT department_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id;
36. Q6. Create a view joining employee and manager names.
CREATE VIEW emp_mgr_view AS
SELECT E.name AS Employee, M.name AS Manager
FROM employees E
LEFT JOIN employees M ON E.manager_id = M.emp_id;
37. Q7. Update an employee’s department via view (if updatable).
UPDATE emp_dept_view SET department_name = 'IT' WHERE name = 'Alice';
38. Q8. Create a view showing employees without managers.
CREATE VIEW no_mgr_view AS
SELECT * FROM employees WHERE manager_id IS NULL;
39. Q9. Use a view in a nested query.
SELECT * FROM emp_dept_view WHERE department_name = 'Sales';
40. Q10. Alter a view to add department ID.
CREATE OR REPLACE VIEW emp_dept_view AS
SELECT E.name, D.department_name, E.department_id
FROM employees E
JOIN departments D ON E.department_id = D.department_id;
5. Stored Procedures – Practice Questions
41. Q1. Create a procedure to show all employees.
DELIMITER //
CREATE PROCEDURE showAllEmployees()
BEGIN
SELECT * FROM employees;
END //
DELIMITER ;
42. Q2. Call the procedure showAllEmployees.
CALL showAllEmployees();
43. Q3. Create a procedure with input parameter (dept ID).
DELIMITER //
CREATE PROCEDURE getEmployeesByDept(IN deptId INT)
BEGIN
SELECT * FROM employees WHERE department_id = deptId;
END //
DELIMITER ;
44. Q4. Call procedure with input parameter.
CALL getEmployeesByDept(3);
45. Q5. Create a procedure to count employees (output parameter).
DELIMITER //
CREATE PROCEDURE countEmployees(OUT total INT)
BEGIN
SELECT COUNT(*) INTO total FROM employees;
END //
DELIMITER ;
46. Q6. Call procedure with output parameter.
CALL countEmployees(@total);
SELECT @total;
47. Q7. Create a procedure to update employee salary.
DELIMITER //
CREATE PROCEDURE updateSalary(IN empId INT, IN newSalary DECIMAL(10,2))
BEGIN
UPDATE employees SET salary = newSalary WHERE emp_id = empId;
END //
DELIMITER ;
48. Q8. Create procedure to delete employee by ID.
DELIMITER //
CREATE PROCEDURE deleteEmployee(IN empId INT)
BEGIN
DELETE FROM employees WHERE emp_id = empId;
END //
DELIMITER ;
49. Q9. Create procedure to return all employees in a view.
DELIMITER //
CREATE PROCEDURE getAllEmpView()
BEGIN
SELECT * FROM emp_dept_view;
END //
DELIMITER ;
50. Q10. Create procedure that returns employees earning above average.
DELIMITER //
CREATE PROCEDURE highEarners()
BEGIN
SELECT * FROM employees WHERE salary > (SELECT AVG(salary) FROM employees);
END //
DELIMITER ;