Advance SQL Challenge 1: Using WINDOWS() and JOIN() Function

365 Days of Coding: Day 17

Today I solved a hard SQL leetcode challenge. I failed in one of the test case and I can’t seem to explain the reason why it failed.

Challenge: Give a table called ‘Employee’ and ‘Department’, I had to find out top 3 highest paying employees in each department.

Table: Employee

IdNameSalaryDepartmentId
1Joe850001
2Henry800002
3Sam600002
4Max900001
5Janet690001
6Randy850001
7Will700001
Sample of the table ‘Employee’

Table: Department

IdName
1IT
2Sales
Sample of the table ‘Department’

Expected Output:

DepartmentEmployeeSalary
ITMax90000
ITRandy85000
ITJoe85000
ITWill70000
SalesHenry80000
SalesSam60000
Sample of the output

My Solution:

SELECT Department, Employee, Salary
FROM (
    SELECT Department, Employee, Salary, 
    ROW_NUMBER () OVER (Partition by Department 
    Order By Salary desc) As rowk 
    FROM (
        Select d.Name AS Department, e.Name AS Employee, 
        e.Salary AS Salary 
        FROM Employee e 
        LEFT JOIN Department d 
        ON e.DepartmentID = d.Id
        ) )
WHERE rowk < 4

My solution failed in one of the test case.

Test Case: The ‘Employee’ table had only one record and the ‘Department’ table had no records.

Table: Employee

IdNameSalaryDepartent Id
1Joe100001
Sample of table ‘Employee’

Table: Department

The Department table for the test case is NULL.

Expected Output From The Test Case

NULL

My above solution gave the following output.

DepartmentEmployeeSalary
nullJoe1000
Sample of the output for the Test Case

After looking at the other solution, I realised that the join should be an ‘INNER JOIN’ rather than a ‘LEFT JOIN’ to pass the test case.

My Revised Solution:

SELECT Department, Employee, Salary
FROM (
    SELECT Department, Employee, Salary, 
    DENSE_RANK () OVER (Partition by Department 
    Order By Salary desc) As rowk 
    FROM (
        Select d.Name AS Department, e.Name AS Employee, 
        e.Salary AS Salary 
        FROM Employee e 
        JOIN Department d 
        ON e.DepartmentID = d.Id
        ) )
WHERE rowk < 4

Other Submitted Solution From the Forums:

Solution 1

WITH agg AS (
SELECT DepartmentId, Name, Salary, DENSE_RANK() OVER (PARTITION BY DepartmentId ORDER BY Salary DESC) AS rank
FROM Employee)

SELECT d.Name AS "Department", a.Name AS "Employee", a.Salary AS "Salary"
FROM agg a 
JOIN Department d ON a.DepartmentId = d.Id
WHERE a.rank < 4
Runtime: 1053 ms

Solution 2

SELECT Department, Employee, Salary
FROM (
    SELECT b.name as Department, a.name as Employee, a.salary,
    DENSE_RANK() 
    OVER(PARTITION BY b.name ORDER BY a.salary DESC) AS rn
    FROM Employee a
        JOIN Department b
        ON a.departmentid = b.id
        GROUP BY b.name, a.name, a.salary
)
WHERE rn <=3
Runtime: 1010 ms

This solution was interesting to know since I didn’t know that a ‘Windows’ operation can be performed with a ‘JOIN’ function.

Solution 3

SELECT D1.Name Department,E.Name Employee,E.salary 
FROM 
Employee E,Department D1,
(SELECT name, dense_rank() OVER (PARTITION BY DepartmentId ORDER BY Salary DESC) sal FROM Employee )e1
 
WHERE E.name = e1.name
 AND e1.sal < 4
 AND E.DepartmentId = D1.Id;
Runtime: 1024 ms

This was another interesting solution cause you can cross join multiple tables including tables that are formed using ‘SELECT’ statement.

Solution 4

SELECT temp.department AS Department,
       temp.employee AS Employee,
       temp.salary AS Salary
FROM (
    SELECT e.name AS employee, 
           e.salary AS salary, 
           d.name AS department,
           DENSE_RANK() OVER (PARTITION BY e.departmentid 
           ORDER BY e.salary DESC) AS rank
    FROM Employee e 
    JOIN Department d
    ON e.departmentid = d.id
) temp
WHERE temp.rank <= 3;
Runtime: 1071 ms

Disclaimer: I am currently learning Oracle SQL. Therefore, the above solutions are only going to work for Oracle SQL. The logic of the language not matter what brand you use will be the same. The only difference will arise from the differences in the syntaxes.

Leave a comment