It is not possible to access an outer table from a derived table (simplifying a bit, this is any "subquery" that requires an alias, in your case g
and a
).
You have to do the required operation on the outer level with a join
. For that, you need to keep track of the o.code_id
and pass it through to the outer level:
SELECT codes.id, sum_date_ranges.sum_date_ranges
FROM codes
JOIN
(SELECT a.code_id, SUM( ... ) as sum_date_ranges
(SELECT g.code_id, g.group_id, MIN( ... ), MAX( ... )
FROM ( SELECT o.code_id, @group_id = ...
FROM dates_range o ...
-- WHERE o.code_id = codes.id -- not required
ORDER BY o.code_id, o.start_date
) g
GROUP BY g.code_id, g.group_id
) a
GROUP BY a.code_id
) as sum_date_ranges
ON sum_date_ranges.code_id = codes.id
-- the rest of your joins and where-conditions
You may need to adept the @group_id = ...
to restart at 0 for every new o.code_id
, but since you do not seem to be using the absolute value anywhere, it probably doesn't matter.
This will evaluate the complete derived table for every code_id
and then throw away everything it doesn't need (which may or may not be a significant part of your data). To prevent that, you can instead actually put the outer conditions inside the query:
SELECT sum_date_ranges.code_id as id, sum_date_ranges.sum_date_ranges
-- from codes -- not required anymore, we get codes.id from derived table
FROM
(SELECT a.code_id, SUM( ... ) as sum_date_ranges
(SELECT g.code_id, g.group_id, MIN( ... ), MAX( ... )
FROM ( SELECT o.code_id, @group_id = ...
FROM dates_range o ...
WHERE o.code_id IN (SELECT codes.id
FROM codes
-- your join and where-conditions
)
ORDER BY o.code_id, o.start_date
) g
GROUP BY g.code_id, g.group_id
) a
GROUP BY a.code_id
) as sum_date_ranges
-- optionally in case you need other columns from codes
-- JOIN codes ON codes.id = sum_date_ranges.code_id
This assumes you actually only need the column codes.id
from codes
(and that your joins
do not multiply your rows), but your query might have been simplified in that regard, so you can of course still join codes
(and other tables) again to get the columns you need (but you do not need a where
-condition here anymore).
It might be possible to completely rewrite your query without a derived table, but it would probably require a lot of modifications and is unlikely to work with variables. It's probably easiest if you start from scratch (and if you need help with that, you would need to provide the complete query, sample data, expected output and some explanation what your code is supposed to do). Specifically, if you use MySQL 8, you can probably use window functions instead of variables to get that kind of ranking, sums, first and last values, although it looks like you still would need a derived table after all.