If you’re getting MySQL error 3582, which reads something like “Window ‘w1’ has a frame definition, so cannot be referenced by another window“, it’s probably because you’re referencing a named window that has a frame clause.
This can happen when we use the WINDOW
clause to define a named window for a window function, and we include a frame clause in that window. When we then try to reference that window, MySQL tells us that we can’t, due to the frame clause.
Here are a couple of options for fixing this issue:
- Try removing any parentheses from the
OVER
clause that references the named window, OR - Don’t include a frame clause in the named window. Instead, try moving the frame clause to the
OVER
clause that references the named window.
Example of Error
Here’s an example of code that produces the error:
SELECT
District,
Name,
Population,
AVG(Population) OVER (w1) AS "Running Average"
FROM City
WHERE CountryCode = 'AUS'
WINDOW w1 AS (PARTITION BY District ORDER BY Name ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
ORDER BY District, Name;
Result:
ERROR 3582 (HY000): Window 'w1' has a frame definition, so cannot be referenced by another window.
Here, the last column in my SELECT
list has an OVER
clause that refers to a named window called w1
. The named window is defined later in the query (in the WINDOW
clause).
However, the named window includes a frame clause, which results in the error when we try to reference the window. In this case, the frame clause is the part that goes ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
.
We’ll also get the error if we refer to it from another named window:
SELECT
District,
Name,
Population,
AVG(Population) OVER (w2) AS "Running Average"
FROM City
WHERE CountryCode = 'AUS'
WINDOW w1 AS (PARTITION BY District ORDER BY Name ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING),
w2 AS (w1)
ORDER BY District, Name;
Result:
ERROR 3582 (HY000): Window 'w1' has a frame definition, so cannot be referenced by another window.
Same error.
In this case, we still get the error, even if we remove all references to any of the named windows in the SELECT
list:
SELECT
District,
Name,
Population,
AVG(Population) OVER () AS "Running Average"
FROM City
WHERE CountryCode = 'AUS'
WINDOW w1 AS (PARTITION BY District ORDER BY Name ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING),
w2 AS (w1)
ORDER BY District, Name;
Result:
ERROR 3582 (HY000): Window 'w1' has a frame definition, so cannot be referenced by another window.
That’s because the second named window (w2
) is trying to reference the first named window (w1
). In this case it has nothing to do with the SELECT
list – the issue in this case is completely within the WINDOW
clause.
Solution 1
The quickest way to deal with this issue is to remove the parentheses from the OVER
clause:
SELECT
District,
Name,
Population,
AVG(Population) OVER w1 AS "Running Average"
FROM City
WHERE CountryCode = 'AUS'
WINDOW w1 AS (PARTITION BY District ORDER BY Name ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
ORDER BY District, Name;
Result:
+-----------------+---------------+------------+-----------------+ | District | Name | Population | Running Average | +-----------------+---------------+------------+-----------------+ | Capital Region | Canberra | 322723 | 322723.0000 | | New South Wales | Central Coast | 227657 | 248990.5000 | | New South Wales | Newcastle | 270324 | 1258062.6667 | | New South Wales | Sydney | 3276207 | 1255430.6667 | | New South Wales | Wollongong | 219761 | 1747984.0000 | | Queensland | Brisbane | 1291117 | 691695.0000 | | Queensland | Cairns | 92273 | 565107.3333 | | Queensland | Gold Coast | 311932 | 171373.0000 | | Queensland | Townsville | 109914 | 210923.0000 | | South Australia | Adelaide | 978100 | 978100.0000 | | Tasmania | Hobart | 126118 | 126118.0000 | | Victoria | Geelong | 125382 | 1495355.5000 | | Victoria | Melbourne | 2865329 | 1495355.5000 | | West Australia | Perth | 1096829 | 1096829.0000 | +-----------------+---------------+------------+-----------------+ 14 rows in set (0.00 sec)
This assumes that it was the OVER
clause that was causing the issue. If the issue was caused by a named window referencing another named window (like in our second example that caused the error), then we’d need to try the next solution.
Solution 2
Another way to deal with the problem is to remove the frame clause away from the named windows.
Therefore, we can move the frame clause up to the OVER
clause in the SELECT
list:
SELECT
District,
Name,
Population,
AVG(Population) OVER (w1 ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS "Running Average"
FROM City
WHERE CountryCode = 'AUS'
WINDOW w1 AS (PARTITION BY District ORDER BY Name)
ORDER BY District, Name;
Result:
+-----------------+---------------+------------+-----------------+ | District | Name | Population | Running Average | +-----------------+---------------+------------+-----------------+ | Capital Region | Canberra | 322723 | 322723.0000 | | New South Wales | Central Coast | 227657 | 248990.5000 | | New South Wales | Newcastle | 270324 | 1258062.6667 | | New South Wales | Sydney | 3276207 | 1255430.6667 | | New South Wales | Wollongong | 219761 | 1747984.0000 | | Queensland | Brisbane | 1291117 | 691695.0000 | | Queensland | Cairns | 92273 | 565107.3333 | | Queensland | Gold Coast | 311932 | 171373.0000 | | Queensland | Townsville | 109914 | 210923.0000 | | South Australia | Adelaide | 978100 | 978100.0000 | | Tasmania | Hobart | 126118 | 126118.0000 | | Victoria | Geelong | 125382 | 1495355.5000 | | Victoria | Melbourne | 2865329 | 1495355.5000 | | West Australia | Perth | 1096829 | 1096829.0000 | +-----------------+---------------+------------+-----------------+ 14 rows in set (0.01 sec)
In this case, moving the frame clause up to the SELECT
list allowed us to reference the named window without error. This option might be more suitable if you have other clauses in the OVER
clause (because this would require that we keep the parentheses).
How to Identify the Frame Clause
If you’re not sure which part of your query is the frame clause, it will be the part that starts with either ROWS
or RANGE
.
See the MySQL documentation for the Window Function Frame Specification for more information.