SQL Practice Questions Complete Guide (1)
SQL Practice Questions Complete Guide (1)
Explanation: This query returns all columns for all records in the Employee table. Use this when you need
complete information about all employees.
Explanation: Returns only the EmployeeName column. Useful when you need specific column data rather than
the entire record.
Explanation: DISTINCT keyword removes duplicate city values, showing each unique city only once.
Explanation: WHERE clause filters records based on the condition. Returns all employees earning more than
50000.
Q5. Display employees from Chennai.
Query:
SELECT * FROM Employee WHERE City = 'Chennai';
Explanation: String comparison in WHERE clause. Returns all records where City equals Chennai.
Explanation: BETWEEN operator checks if a value falls within a specified range (inclusive of boundaries).
Explanation: LIKE with % wildcard. A% matches any string starting with A. % represents zero or more characters.
Explanation: %n matches any string ending with n. % can appear before or after the pattern.
Q9. Display employees whose name contains 'ra'.
Query:
SELECT * FROM Employee WHERE EmployeeName LIKE '%ra%';
Explanation: YEAR() function extracts the year from a date. Alternatively: HireDate > '2023-12-31'
Explanation: Returns employees hired in 2021 and earlier. YEAR() simplifies date comparisons.
Explanation: IN operator checks if City matches any value in the list. Cleaner than multiple OR conditions.
Q13. Display employees not from Chennai.
Query:
SELECT * FROM Employee WHERE City != 'Chennai'; -- or WHERE City <> 'Chennai';
Explanation: NOT operator or != (or <>) filters out records. Returns all employees from cities other than Chennai.
Explanation: IS NULL checks for missing values. Use IS NULL (not = NULL) to check NULL values.
Explanation: Returns only employees who have a manager assigned (non-NULL ManagerID).
Explanation: ORDER BY Salary DESC sorts by salary (highest first), TOP/LIMIT restricts to 5 rows.
Q17. Display employees ordered by salary ascending.
Query:
SELECT * FROM Employee ORDER BY Salary ASC;
Explanation: ASC sorts lowest to highest. ASC is default, so ORDER BY Salary works the same way.
Explanation: DESC sorts highest to lowest. Useful for finding top earners or best performers.
Explanation: Sorts names alphabetically A→Z. Can also use DESC for reverse alphabetical order.
Explanation: LIMIT (MySQL) or TOP (SQL Server) restricts output to specified number of rows.
Level 2 - Aggregate Functions (21-35)
Explanation: COUNT(*) counts all rows. COUNT(column) counts non-NULL values in that column.
Explanation: GROUP BY groups rows by Department, COUNT(*) counts employees in each group.
Explanation: MAX() returns the highest value. Other aggregate functions: MIN, SUM, AVG, COUNT.
Explanation: AVG() calculates the average (sum/count). Good for understanding typical salary levels.
Explanation: SUM() adds all values. Useful for budgeting and total expense calculations.
Explanation: GROUP BY Department creates groups, AVG(Salary) calculates average per group.
Explanation: MAX(Salary) with GROUP BY finds the highest earner in each department.
Q29. Find lowest salary in each department.
Query:
SELECT Department, MIN(Salary) as MinSalary FROM Employee GROUP BY Department;
Explanation: MIN(Salary) with GROUP BY finds the lowest earner in each department.
Explanation: HAVING filters groups (after GROUP BY). WHERE filters rows (before GROUP BY).
Explanation: Groups employees by City and counts them. Shows distribution across locations.
Explanation: Counts all project assignment records. Indicates total workload across team.
Q33. Count customers from each city.
Query:
SELECT City, COUNT(*) as CustomerCount FROM Customer GROUP BY City;
Explanation: Calculates average performance across all students. Helpful for benchmarking.
Explanation: HAVING filters groups based on aggregate function results. Useful for finding high-paying
departments.
Q37. Display cities having more than 10 employees.
Query:
SELECT City, COUNT(*) as EmployeeCount FROM Employee GROUP BY City HAVING COUNT(*) > 10;
Explanation: Shows cities with significant workforce. Helps in office capacity planning.
Explanation: Combines GROUP BY, ORDER BY, and TOP to find the single department with highest average
salary.
Explanation: ASC order finds lowest average. Identifies departments that might need salary reviews.
Explanation: Shows total payroll expense per department. Important for budgeting.
Q41. Display products sold more than 50 times.
Query:
SELECT ProductName, COUNT(*) as SaleCount FROM Sales GROUP BY ProductName HAVING COUNT(*) >
50;
Explanation: Shows order frequency per customer. Helps identify loyal/valuable customers.
Explanation: Groups sales by month and year, calculates total. Shows sales trends over time.
Explanation: Shows average student performance by department. Useful for curriculum evaluation.
Q45. Find departments having exactly 5 employees.
Query:
SELECT Department, COUNT(*) as EmployeeCount FROM Employee GROUP BY Department HAVING COUNT(*)
= 5;
Explanation: HAVING with equality operator. Shows departments with specific team size.
Explanation: UPPER() converts all characters to uppercase. Useful for standardized formatting.
Explanation: LOWER() converts all characters to lowercase. Helps with case-insensitive comparisons.
Explanation: LEN() returns character count. Useful for validation (e.g., names should be 2-50 chars).
Q49. Display first three letters of employee names.
Query:
SELECT EmployeeName, LEFT(EmployeeName, 3) as FirstThreeLetters FROM Employee;
Explanation: LTRIM() removes spaces from left. RTRIM() removes from right. TRIM() removes both sides.
Explanation: REPLACE(string, search, replacement) replaces all occurrences. Case-sensitive in most databases.
Explanation: CONCAT() combines strings. CONCAT_WS() allows separator. Alternative: EmployeeName + ' - ' +
City
Q53. Reverse employee names.
Query:
SELECT EmployeeName, REVERSE(EmployeeName) as ReversedName FROM Employee;
Explanation: REVERSE() flips string order. Useful for palindrome checks or data manipulation.
Explanation: LEFT() gets first character. For multiple initials, use SUBSTRING() or multiple LEFT() calls.
Explanation: LEN() counts characters including spaces. Useful for data validation and analysis.
Explanation: GETDATE() returns current date and time. CURDATE() returns only date (MySQL).
Q57. Find employees hired this year.
Query:
SELECT * FROM Employee WHERE YEAR(HireDate) = YEAR(GETDATE());
Explanation: YEAR() extracts year from date. GETDATE() returns current date. Compares year values.
Explanation: MONTH() extracts month. This finds employees hired in the previous month.
Explanation: DATEDIFF() calculates difference between dates. Format: DATEDIFF(unit, start_date, end_date).
Explanation: Filters sales from current month using MONTH() and YEAR(), then sums amounts.
Q61. Display previous month's sales.
Query:
SELECT SUM(Amount) as PreviousMonthSales FROM Sales WHERE MONTH(OrderDate) = MONTH(GETDATE())
- 1 AND YEAR(OrderDate) = YEAR(GETDATE());
Explanation: CAST converts datetime to DATE for comparison. Ignores time portion.
Explanation: Groups sales by year and calculates total per year. Shows revenue trends annually.
Explanation: INNER JOIN connects Employee and Department tables. Returns only matching records from both
tables.
Explanation: LEFT JOIN keeps all employees, WHERE DepartmentID IS NULL finds those without department
assignment.
Explanation: RIGHT JOIN or LEFT JOIN (reversed) keeps all departments. COUNT shows employees per dept (0
if none).
Q69. Display employees and their managers.
Query:
SELECT [Link] as Employee, [Link] as Manager FROM Employee e LEFT JOIN
Employee m ON [Link] = [Link];
Explanation: Self-join: joining Employee table to itself. Connects employees to their managers.
Explanation: Combines Customer and Orders tables using INNER JOIN for customer-order pairs.
Explanation: LEFT JOIN with IS NULL finds products with no matching sales records.
Explanation: Identifies inactive customers. Useful for marketing campaigns or customer retention analysis.
Q73. Display employees working on projects.
Query:
SELECT DISTINCT [Link], [Link] FROM Employee e INNER JOIN ProjectAssignment pa
ON [Link] = [Link] INNER JOIN Project p ON [Link] = [Link];
Explanation: Multiple INNER JOINs connect three tables. DISTINCT removes duplicate rows.
Explanation: Combines JOIN with GROUP BY and SUM for aggregate data per department.
Explanation: Connecting three tables to show which employees work on which projects.
Explanation: Self-join with COALESCE handles NULL managers. COALESCE provides default value if NULL.
Q77. Display all products with sales quantity.
Query:
SELECT [Link], SUM([Link]) as TotalQuantitySold FROM Product p LEFT JOIN Sales s ON
[Link] = [Link] GROUP BY [Link], [Link];
Explanation: LEFT JOIN shows all products even if not sold. GROUP BY with SUM calculates total sold quantity.
Explanation: Combines JOIN, GROUP BY, ORDER BY, and TOP to find largest department.
Explanation: Uses subquery to calculate department average, then filters employees above that average.
Level 7 - Subqueries (81-90)
Explanation: Subquery finds max salary, outer query returns the employee with that salary.
Explanation: Nested subqueries: inner finds max, middle finds second max, outer returns employee.
Explanation: Can be solved with TOP/LIMIT or complex nested subqueries. TOP method is simpler.
Explanation: Subquery calculates average, outer query returns employees above that average.
Q85. Find departments with no employees.
Query:
SELECT * FROM Department WHERE DepartmentID NOT IN (SELECT DISTINCT DepartmentID FROM
Employee);
Explanation: NOT IN with subquery finds departments not in the employee list.
Explanation: Subquery calculates average product price, outer query returns above-average products.
Explanation: Multiple subqueries: inner finds max amount, middle finds customer with that amount, outer returns
details.
Explanation: Correlated subquery: inner query references outer query's Department value.
Q89. Find employees in department with highest salary.
Query:
SELECT * FROM Employee WHERE DepartmentID = (SELECT DepartmentID FROM (SELECT TOP 1
DepartmentID, AVG(Salary) as AvgSal FROM Employee GROUP BY DepartmentID ORDER BY AvgSal DESC)
as T);
Explanation: Complex subquery: finds department with highest average salary, then returns all employees in that
dept.
Explanation: Counts distinct products per customer, compares to total products. Customers with all = count
matches total.
Explanation: RANK() assigns rank but skips numbers after ties (1,2,2,4). Useful for competitions with ties.
Explanation: DENSE_RANK() doesn't skip numbers (1,2,2,3). Preferred when ties shouldn't affect numbering.
Q93. Row Number for employees.
Query:
SELECT EmployeeID, EmployeeName, Salary, ROW_NUMBER() OVER (ORDER BY Salary DESC) as RowNum
FROM Employee;
Explanation: ROW_NUMBER() gives unique sequential numbers even for ties (1,2,3,4). Assigns unique rank.
Explanation: PARTITION BY creates groups per department, RANK ranks within each group. Add WHERE
DeptRank = 1 for top only.
Explanation: Uses window function in subquery, then filters for rank=2. Shows second-highest earner per dept.
Explanation: SUM() with ORDER BY creates cumulative total. Shows sales buildup over time.
Q97. Calculate cumulative salary.
Query:
SELECT EmployeeName, Salary, SUM(Salary) OVER (ORDER BY EmployeeID) as CumulativeSalary FROM
Employee;
Explanation: Cumulative total of salaries ordered by EmployeeID. Shows total payroll buildup.
Explanation: LAG() accesses previous row's value. Useful for comparing current to previous (salary, price, etc).
Explanation: LEAD() accesses next row's value. Opposite of LAG(). Useful for forward-looking comparisons.
Explanation: NTILE(4) divides employees into 4 equal groups. Values 1-4 represent quartiles (0-25%, 25-50%,
etc).
Bonus: Interview Questions (Frequently Asked)
Explanation: Groups by column and counts occurrences. HAVING count > 1 shows duplicates.
Explanation: Keeps only the first occurrence (MIN RowID), deletes rest. Requires unique identifier column.
Explanation: Gets top N rows, then returns minimum (which is Nth). Substitute N with desired number.
Explanation: Finds max salary less than the overall max. Avoids using LIMIT/TOP/NTILE.
Q105. Find employees with same salary.
Query:
SELECT [Link], [Link] FROM Employee e1 INNER JOIN Employee e2 ON [Link] =
[Link] AND [Link] != [Link];
Explanation: Self-join matches employees with equal salaries but different IDs.
Explanation: Self-join with filter. Shows cases where employee earns more than their manager.
Explanation: Groups by ManagerID, counts subordinates, filters for those with >5 employees.
Explanation: Direct update swaps values. Alternative: use temporary variable (UPDATE ... SET Column1=@temp,
@temp=Column2).
Q109. Pivot rows into columns.
Query:
SELECT Department, [Software] as SoftwareSales, [Hardware] as HardwareSales, [Services] as
ServicesSales FROM (SELECT Department, ProductCategory, Amount FROM Sales) T PIVOT
(SUM(Amount) FOR ProductCategory IN ([Software], [Hardware], [Services])) as PivotTable;
Explanation: PIVOT rotates rows to columns. Useful for creating cross-tabulation reports.
Explanation: UNPIVOT converts columns to rows. Opposite of PIVOT. Normalizes denormalized data.