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?
Advertisement
Answer
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;