I have such MySQL code:
SELECT
departmentId,
name,
salary,
DENSE_RANK() OVER (PARTITION BY departmentId ORDER BY salary DESC) AS salary_rank
FROM Employee
HAVING departmentId = 1
This works properly as expected but if I change the HAVING clause as
SELECT
departmentId,
name,
salary,
DENSE_RANK() OVER (PARTITION BY departmentId ORDER BY salary DESC) AS salary_rank
FROM Employee
HAVING salary_rank = 1
It wouldn’t get passed.
Why HAVING clause is not abled to do such filtering, for HAVING clause "taking effect after query"?
2
Answers
While MySQL has overloaded the
HAVING
operator to allow referring to aliases, it does not work with window functions. The reason for this is that the window functions generally evaluate last in the pipeline. This means that, in your second query, the dense rank calculation would not have completed when it would be needed to filter. In this case, the workaround is to simply use a proper subquery:Formally, it should be assumed that window functions are processed/evaluated after processing the HAVING clause and calculating all output columns, except those in expressions for which some window function is used, but before processing the ORDER BY.
Thus, expressions that use window functions have not yet been evaluated at the time of processing the HAVING clause.