SQL Server Window Functions - Examples
Sample Table: Employees
| EmpID | Name | Department | Salary |
|-------|--------|------------|--------|
|1 | Ali | IT | 80000 |
|2 | Sara | HR | 60000 |
|3 | Ahmed | IT | 75000 |
|4 | Hina | HR | 60000 |
|5 | Usman | IT | 90000 |
1. ROW_NUMBER() - Unique row number ordered by salary
SELECT Name, Department, Salary,
ROW_NUMBER() OVER (ORDER BY Salary DESC) AS RowNum
FROM Employees;
Output:
| Name | Dept | Salary | RowNum |
|-------|------|--------|--------|
| Usman | IT | 90000 | 1 |
| Ali | IT | 80000 | 2 |
| Ahmed | IT | 75000 | 3 |
| Sara | HR | 60000 | 4 |
| Hina | HR | 60000 | 5 |
2. RANK() vs DENSE_RANK() - Handling ties
SELECT Name, Salary,
RANK() OVER (ORDER BY Salary DESC) AS Rank,
DENSE_RANK() OVER (ORDER BY Salary DESC) AS DenseRank
FROM Employees;
Output:
| Name | Salary | Rank | DenseRank |
|-------|--------|------|-----------|
| Usman | 90000 | 1 |1 |
| Ali | 80000 | 2 |2 |
| Ahmed | 75000 | 3 |3 |
| Sara | 60000 | 4 |4 |
| Hina | 60000 | 4 |4 |
3. NTILE(3) - Divide into 3 groups
SELECT Name, Salary,
NTILE(3) OVER (ORDER BY Salary DESC) AS GroupNum
FROM Employees;
Output:
| Name | Salary | GroupNum |
|-------|--------|----------|
| Usman | 90000 | 1 |
| Ali | 80000 | 1 |
| Ahmed | 75000 | 2 |
| Sara | 60000 | 3 |
| Hina | 60000 | 3 |
4. LAG() and LEAD() - Previous and Next salary
SELECT Name, Salary,
LAG(Salary) OVER (ORDER BY Salary) AS PrevSalary,
LEAD(Salary) OVER (ORDER BY Salary) AS NextSalary
FROM Employees;
Output:
| Name | Salary | PrevSalary | NextSalary |
|-------|--------|------------|------------|
| Sara | 60000 | NULL | 60000 |
| Hina | 60000 | 60000 | 75000 |
| Ahmed | 75000 | 60000 | 80000 |
| Ali | 80000 | 75000 | 90000 |
| Usman | 90000 | 80000 | NULL |
5. SUM() - Running total of salary
SELECT Name, Salary,
SUM(Salary) OVER (ORDER BY Salary) AS RunningTotal
FROM Employees;
Output:
| Name | Salary | RunningTotal |
|-------|--------|--------------|
| Sara | 60000 | 60000 |
| Hina | 60000 | 120000 |
| Ahmed | 75000 | 195000 |
| Ali | 80000 | 275000 |
| Usman | 90000 | 365000 |
6. AVG() with PARTITION BY - Average per department
SELECT Name, Department, Salary,
AVG(Salary) OVER (PARTITION BY Department) AS DeptAvgSalary
FROM Employees;
Output:
| Name | Dept | Salary | DeptAvgSalary |
|-------|------|--------|----------------|
| Ali | IT | 80000 | 81666.66 |
| Ahmed | IT | 75000 | 81666.66 |
| Usman | IT | 90000 | 81666.66 |
| Sara | HR | 60000 | 60000.00 |
| Hina | HR | 60000 | 60000.00 |