SQL Programming Practice Paper – Set 2 (With Answers)
Section A: Basics & DDL/DML (10 Marks)
1. Q1. Define Primary Key vs Unique Key.
- Primary Key ensures each row is unique and cannot contain NULLs.
- Unique Key also ensures uniqueness but allows a single NULL value.
2. Q2. Create a `Departments` table.
CREATE TABLE Departments (
DeptID INT PRIMARY KEY,
DeptName VARCHAR(100),
Location VARCHAR(50)
);
3. Q3. Insert a record into `Departments`.
INSERT INTO Departments (DeptID, DeptName, Location)
VALUES (1, 'Finance', 'Mumbai');
4. Q4. Delete department where `DeptName = 'Finance'`.
DELETE FROM Departments WHERE DeptName = 'Finance';
5. Q5. Rename column `Location` to `City`.
ALTER TABLE Departments RENAME COLUMN Location TO City;
Section B: SELECT Queries & Filtering (10 Marks)
6. Q6. Get all employees from 'HR' department.
SELECT * FROM Employees WHERE Department = 'HR';
7. Q7. Find employees whose names end with 'a'.
SELECT * FROM Employees WHERE FirstName LIKE '%a';
8. Q8. List employees who joined in 2023.
SELECT * FROM Employees WHERE YEAR(JoinDate) = 2023;
9. Q9. Find employees not in 'Finance' department.
SELECT * FROM Employees WHERE Department <> 'Finance';
10. Q10. Show salary of employees in ascending order.
SELECT FirstName, LastName, Salary FROM Employees ORDER BY Salary ASC;
Section C: JOINS & Relationships (15 Marks)
11. Q11. Get list of employees along with their department name.
SELECT E.FirstName, D.DeptName FROM Employees E
JOIN Departments D ON E.DeptID = D.DeptID;
12. Q12. Fetch employees with or without departments.
SELECT E.FirstName, D.DeptName FROM Employees E
LEFT JOIN Departments D ON E.DeptID = D.DeptID;
13. Q13. List departments without any employees.
SELECT D.DeptName FROM Departments D
LEFT JOIN Employees E ON D.DeptID = E.DeptID
WHERE E.EmpID IS NULL;
14. Q14. Count employees in each city.
SELECT City, COUNT(*) AS EmployeeCount FROM Employees GROUP BY City;
15. Q15. Get department name for each employee using aliases.
SELECT E.FirstName, D.DeptName AS Department FROM Employees E
INNER JOIN Departments D ON E.DeptID = D.DeptID;
Section D: Subqueries & Aggregations (15 Marks)
16. Q16. Get employee(s) with lowest salary.
SELECT * FROM Employees WHERE Salary = (SELECT MIN(Salary) FROM Employees);
17. Q17. Get department-wise highest salary.
SELECT DeptID, MAX(Salary) FROM Employees GROUP BY DeptID;
18. Q18. List employees earning more than department average.
SELECT * FROM Employees E1
WHERE Salary > (SELECT AVG(Salary) FROM Employees E2 WHERE E2.DeptID =
E1.DeptID);
19. Q19. Get all employees whose salary is not among top 3.
SELECT * FROM Employees
WHERE Salary NOT IN (
SELECT DISTINCT Salary FROM Employees ORDER BY Salary DESC LIMIT 3
);
20. Q20. Find second highest salary using subquery.
SELECT MAX(Salary) FROM Employees
WHERE Salary < (SELECT MAX(Salary) FROM Employees);
Section E: Group By, Having, Case & Window Functions (20 Marks)
21. Q21. Total and average salary per department.
SELECT DeptID, SUM(Salary) AS Total, AVG(Salary) AS Average
FROM Employees GROUP BY DeptID;
22. Q22. Departments with more than 5 employees.
SELECT DeptID, COUNT(*) AS EmpCount FROM Employees
GROUP BY DeptID HAVING COUNT(*) > 5;
23. Q23. Assign performance rating by salary slab.
SELECT *, CASE
WHEN Salary >= 90000 THEN 'Excellent'
WHEN Salary >= 70000 THEN 'Good'
ELSE 'Average' END AS Rating
FROM Employees;
24. Q24. Find Dense Rank of salary within departments.
SELECT *, DENSE_RANK() OVER (PARTITION BY DeptID ORDER BY Salary DESC) AS
RankInDept
FROM Employees;
25. Q25. Calculate running total salary per department.
SELECT *, SUM(Salary) OVER (PARTITION BY DeptID ORDER BY JoinDate) AS RunningTotal
FROM Employees;
Section F: Practical SQL Challenge (30 Marks)
26. Q26. Top 2 highest spending customers from 'Orders'.
SELECT CustomerID, SUM(Amount) AS TotalSpent
FROM Orders GROUP BY CustomerID ORDER BY TotalSpent DESC LIMIT 2;
27. Q27. Find customers who placed at least 3 orders.
SELECT CustomerID FROM Orders
GROUP BY CustomerID HAVING COUNT(*) >= 3;
28. Q28. Show daily order count in April 2024.
SELECT OrderDate, COUNT(*) AS Orders
FROM Orders
WHERE OrderDate BETWEEN '2024-04-01' AND '2024-04-30'
GROUP BY OrderDate;
29. Q29. Identify most recent order per customer.
SELECT * FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY CustomerID ORDER BY OrderDate
DESC) AS rn
FROM Orders
) AS sub WHERE rn = 1;
30. Q30. Calculate order amount percent contribution per day.
SELECT OrderDate,
Amount,
ROUND(Amount * 100.0 / SUM(Amount) OVER (PARTITION BY OrderDate), 2) AS
PercentContribution
FROM Orders;
SQL Programming Practice Papers – Set 3 & Set 4 (With Answers)
Set 3
Section A: Basics & Table Management
31. Q1. Explain the difference between CHAR and VARCHAR.
- CHAR is fixed-length and pads with spaces. VARCHAR is variable-length and stores only
actual characters.
32. Q2. Create a `Products` table.
CREATE TABLE Products (
ProductID INT PRIMARY KEY,
ProductName VARCHAR(100),
Price DECIMAL(8,2),
Category VARCHAR(50)
);
33. Q3. Insert two products into the table.
INSERT INTO Products VALUES (1, 'Laptop', 75000.00, 'Electronics');
INSERT INTO Products VALUES (2, 'Chair', 3000.00, 'Furniture');
34. Q4. Update price of product with ID = 2.
UPDATE Products SET Price = 3200.00 WHERE ProductID = 2;
35. Q5. Delete all records from Products table.
DELETE FROM Products;
Section B: SELECT & Conditions
36. Q6. List products with price above 5000.
SELECT * FROM Products WHERE Price > 5000;
37. Q7. Retrieve products in Electronics category.
SELECT * FROM Products WHERE Category = 'Electronics';
38. Q8. Display all categories (no duplicates).
SELECT DISTINCT Category FROM Products;
39. Q9. Retrieve products not in Furniture category.
SELECT * FROM Products WHERE Category <> 'Furniture';
40. Q10. Sort products by price descending.
SELECT * FROM Products ORDER BY Price DESC;
Set 4
Section C: JOINS & Aggregates
41. Q11. List employees and their department names.
SELECT E.FirstName, D.DeptName FROM Employees E
JOIN Departments D ON E.DeptID = D.DeptID;
42. Q12. List employees with department even if department is null.
SELECT E.FirstName, D.DeptName FROM Employees E
LEFT JOIN Departments D ON E.DeptID = D.DeptID;
43. Q13. Find departments with no employees.
SELECT D.DeptName FROM Departments D
LEFT JOIN Employees E ON D.DeptID = E.DeptID
WHERE E.EmpID IS NULL;
44. Q14. Total employees in each department.
SELECT DeptID, COUNT(*) FROM Employees GROUP BY DeptID;
45. Q15. Average salary per department.
SELECT DeptID, AVG(Salary) FROM Employees GROUP BY DeptID;
Section D: Subqueries, CASE, and Window Functions
46. Q16. Employees earning more than avg salary.
SELECT * FROM Employees WHERE Salary > (SELECT AVG(Salary) FROM Employees);
47. Q17. Display employees with rank by salary.
SELECT *, RANK() OVER (ORDER BY Salary DESC) AS SalaryRank FROM Employees;
48. Q18. Add experience level based on years.
SELECT *, CASE
WHEN DATEDIFF(CURDATE(), JoinDate)/365 > 5 THEN 'Senior'
WHEN DATEDIFF(CURDATE(), JoinDate)/365 > 2 THEN 'Mid'
ELSE 'Junior' END AS ExperienceLevel
FROM Employees;
49. Q19. Find total salary in each department using window function.
SELECT *, SUM(Salary) OVER (PARTITION BY DeptID) AS TotalDeptSalary FROM
Employees;
50. Q20. Fetch top 2 earners in each department.
SELECT * FROM (
SELECT *, RANK() OVER (PARTITION BY DeptID ORDER BY Salary DESC) AS rk FROM
Employees
) sub WHERE rk <= 2;
SQL Programming Practice Papers – Set 5 & Set 6 (With Answers)
Set 5
Section A: Advanced Filtering & Aggregations
51. Q1. Find employees earning within top 10% salaries.
SELECT * FROM Employees WHERE Salary >= (
SELECT PERCENTILE_CONT(0.9) WITHIN GROUP (ORDER BY Salary) OVER ()
);
52. Q2. Find employees who joined in last 6 months.
SELECT * FROM Employees WHERE JoinDate >= DATE_SUB(CURDATE(), INTERVAL 6
MONTH);
53. Q3. Department-wise highest paid employee.
SELECT * FROM Employees E WHERE Salary = (
SELECT MAX(Salary) FROM Employees WHERE DeptID = E.DeptID
);
54. Q4. Departments where no one earns more than 70,000.
SELECT DeptID FROM Employees GROUP BY DeptID HAVING MAX(Salary) <= 70000;
55. Q5. Total, max, min salary by department.
SELECT DeptID, SUM(Salary), MAX(Salary), MIN(Salary) FROM Employees GROUP BY
DeptID;
Section B: Case, Ranking, and Advanced Joins
56. Q6. Classify employees into salary grades.
SELECT *, CASE
WHEN Salary >= 90000 THEN 'A'
WHEN Salary >= 70000 THEN 'B'
ELSE 'C' END AS Grade FROM Employees;
57. Q7. List top earning employee in each department.
SELECT * FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY DeptID ORDER BY Salary DESC) AS rn
FROM Employees
) AS sub WHERE rn = 1;
58. Q8. List employees with department and manager name.
SELECT E.FirstName, D.DeptName, M.FirstName AS ManagerName
FROM Employees E
JOIN Departments D ON E.DeptID = D.DeptID
JOIN Employees M ON E.ManagerID = M.EmpID;
59. Q9. Employees with duplicate salaries.
SELECT * FROM Employees WHERE Salary IN (
SELECT Salary FROM Employees GROUP BY Salary HAVING COUNT(*) > 1
);
60. Q10. List employees who joined in same month as someone else.
SELECT * FROM Employees E1 WHERE EXISTS (
SELECT 1 FROM Employees E2
WHERE MONTH(E1.JoinDate) = MONTH(E2.JoinDate) AND E1.EmpID <> E2.EmpID
);
Set 6
Section C: Subqueries, CTEs, and Window Analytics
61. Q11. Using CTE, calculate average salary per department and list employees above that.
WITH DeptAvg AS (
SELECT DeptID, AVG(Salary) AS AvgSal FROM Employees GROUP BY DeptID
)
SELECT E.* FROM Employees E
JOIN DeptAvg D ON E.DeptID = D.DeptID
WHERE E.Salary > D.AvgSal;
62. Q12. Rank employees based on JoinDate company-wide.
SELECT *, RANK() OVER (ORDER BY JoinDate ASC) AS JoinRank FROM Employees;
63. Q13. Show department-wise salary percentile (75%).
SELECT DISTINCT DeptID, PERCENTILE_CONT(0.75) WITHIN GROUP (ORDER BY Salary)
OVER (PARTITION BY DeptID) AS Perc75
FROM Employees;
64. Q14. Cumulative average salary by department.
SELECT *, AVG(Salary) OVER (PARTITION BY DeptID ORDER BY JoinDate ROWS BETWEEN
UNBOUNDED PRECEDING AND CURRENT ROW) AS CumAvg
FROM Employees;
65. Q15. Get last 3 joiners in IT department.
SELECT * FROM (
SELECT *, RANK() OVER (PARTITION BY DeptID ORDER BY JoinDate DESC) AS rk FROM
Employees
) AS sub
WHERE DeptID = (SELECT DeptID FROM Departments WHERE DeptName = 'IT') AND rk <=
3;
Section D: Real-World Scenarios & Optimization
66. Q16. Find revenue per category for last quarter.
SELECT Category, SUM(Amount) AS Revenue FROM Orders
WHERE OrderDate BETWEEN DATE_SUB(CURDATE(), INTERVAL 3 MONTH) AND
CURDATE()
GROUP BY Category;
67. Q17. Detect customers who placed orders every month this year.
SELECT CustomerID FROM Orders
WHERE YEAR(OrderDate) = YEAR(CURDATE())
GROUP BY CustomerID
HAVING COUNT(DISTINCT MONTH(OrderDate)) = 12;
68. Q18. Identify employees without recent performance review.
SELECT * FROM Employees WHERE EmpID NOT IN (
SELECT EmpID FROM PerformanceReviews
WHERE ReviewDate >= DATE_SUB(CURDATE(), INTERVAL 1 YEAR)
);
69. Q19. Optimize: replace correlated subquery with join.
-- Original:
SELECT * FROM Employees WHERE DeptID IN (SELECT DeptID FROM Departments WHERE
Location = 'Delhi');
-- Optimized:
SELECT E.* FROM Employees E JOIN Departments D ON E.DeptID = D.DeptID WHERE
D.Location = 'Delhi';
70. Q20. Identify customers with order gaps > 90 days.
SELECT CustomerID, OrderDate,
LAG(OrderDate) OVER (PARTITION BY CustomerID ORDER BY OrderDate) AS PrevOrder,
DATEDIFF(OrderDate, LAG(OrderDate) OVER (PARTITION BY CustomerID ORDER BY
OrderDate)) AS GapDays
FROM Orders
HAVING GapDays > 90;
SQL Programming Practice Paper – Set 7: Business Case Scenarios &
Debugging (With Answers)
Section A: Business Case Scenarios (15 Marks)
71. Q1. A retail company wants to identify its top 5 selling products in the last financial year.
Write a query to return the product name and total sales amount.
SELECT ProductName, SUM(Amount) AS TotalSales
FROM Sales
WHERE OrderDate BETWEEN '2023-04-01' AND '2024-03-31'
GROUP BY ProductName
ORDER BY TotalSales DESC
LIMIT 5;
72. Q2. A manager wants to identify employees who haven't taken any leaves in the current
calendar year.
SELECT E.EmpID, E.FirstName, E.LastName
FROM Employees E
WHERE E.EmpID NOT IN (
SELECT DISTINCT EmpID FROM Leaves
WHERE YEAR(LeaveDate) = YEAR(CURDATE())
);
73. Q3. The finance team wants to audit all customers who have made purchases over 1
lakh across any month in 2024.
SELECT CustomerID, MONTH(OrderDate) AS Month, SUM(Amount) AS MonthlyTotal
FROM Orders
WHERE YEAR(OrderDate) = 2024
GROUP BY CustomerID, MONTH(OrderDate)
HAVING MonthlyTotal > 100000;
74. Q4. Identify employees who have changed departments more than twice in the past
year.
SELECT EmpID FROM DepartmentTransfers
WHERE TransferDate BETWEEN DATE_SUB(CURDATE(), INTERVAL 1 YEAR) AND
CURDATE()
GROUP BY EmpID
HAVING COUNT(*) > 2;
75. Q5. HR wants a report showing headcount by department and gender.
SELECT DeptID, Gender, COUNT(*) AS Headcount
FROM Employees
GROUP BY DeptID, Gender;
Section B: Debugging SQL Queries (15 Marks)
76. Q6. The following query is giving wrong results. Debug and correct it:
SELECT * FROM Employees WHERE Salary > AVG(Salary);
-- Error: Aggregate functions cannot be used directly in WHERE clause.
-- Fix:
SELECT * FROM Employees WHERE Salary > (SELECT AVG(Salary) FROM Employees);
77. Q7. The query below is throwing a syntax error. Identify and fix it:
SELECT FirstName, LastName FROM Employees ORDER Salary DESC;
-- Error: Missing BY keyword.
-- Fix:
SELECT FirstName, LastName FROM Employees ORDER BY Salary DESC;
78. Q8. Fix this query to return department-wise second highest salary:
SELECT MAX(Salary) FROM Employees WHERE Salary < MAX(Salary) GROUP BY
DeptID;
-- Error: MAX inside WHERE is invalid.
-- Fix:
SELECT DeptID, MAX(Salary) FROM Employees
WHERE (DeptID, Salary) IN (
SELECT DeptID, MAX(Salary) FROM Employees
WHERE Salary < (SELECT MAX(Salary) FROM Employees E2 WHERE E2.DeptID =
Employees.DeptID)
GROUP BY DeptID
);
79. Q9. Correct this join syntax:
SELECT * FROM Employees E JOIN Departments D E.DeptID = D.DeptID;
-- Error: Missing ON keyword.
-- Fix:
SELECT * FROM Employees E JOIN Departments D ON E.DeptID = D.DeptID;
80. Q10. The following query gives NULL for all rankings. Identify the problem:
SELECT FirstName, RANK() OVER (ORDER Salary DESC) AS Rank FROM Employees;
-- Error: Missing BY keyword in ORDER clause.
-- Fix:
SELECT FirstName, RANK() OVER (ORDER BY Salary DESC) AS Rank FROM Employees;