Search code examples
sqloracle-databasesubquerycommon-table-expression

'WITH' clause does not work with in operator


I have a simple query:

with MaxSal AS (SELECT MAX(Salary), DepartmentId FROM Employee GROUP BY DepartmentId)
SELECT Department.Name AS "Department", Employee.Name AS "Employee", Employee.Salary AS "Salary" FROM Employee
JOIN Department ON Department.Id = Employee.DepartmentId
WHERE (Employee.Salary, Employee.DepartmentId) in MaxSal;

It should create a MaxSal temporary table and then in the WHERE section it should check whether the Salary, DepId are inside said table. Unfortunately, this query gives me ORA-00920: invalid relational operator which I guess is referring to the in operator. If I put the Sub-query directly instead of first putting it in a temp table, everything works as expected.
Can somebody tell me why it isn't working with the WITH clause?


Solution

  • You need a table reference to refer to the CTE and that, in turn, requires a FROM clause. You can do what you want using a subquery

    WITH MaxSal AS (
          SELECT MAX(Salary) as max_salary, DepartmentId
          FROM Employee
          GROUP BY DepartmentId
         )
    SELECT d.Name AS Department, e.Name AS Employee, 
           e.Salary AS Salary
    FROM Employee e JOIN
         Department d
         ON d.Id = e.DepartmentId
    WHERE (e.Salary, e.DepartmentId) in (SELECT max_salary, DepartmentId) FROM MaxSal);
    

    That said, RANK() is much simpler:

    SELECT Department, Name AS Employee, Salary
    FROM (SELECT e.*, d.Name as Department,
                 RANK() OVER (PARTITION BY d.id ORDER BY e.Salary DESC) as seqnum
          FROM Employee e JOIN
               Department d
               ON d.Id = e.DepartmentId
         ) ed
    WHERE seqnum = 1;