On the specefic error, is id_empresa is actually a column in cuotasindical.pagos?
If it isn't, i think the optimizer could be getting confused because the having clause has the information for something in the group by... the "having P1.periodo in ()". P1.periodo is also a group by.
As i understand it, group by is for fields that are not aggregates. Where is for fields that are not aggregates.
Having is the weierd one... that "filters based on what you have aggregatede"> You haven't aggregated P1.periodo, but if that is the issue that error message is somewhat decieving.
I would consider for debugging and visibility to look at CTE's (common table expressions) if your database supports it. (Not sure about the latest MySQL).
If it doesn't support it, try using a view... you have quite a bit of code there all referencing the same two tables. Maybe it would be a good idea to generate a data set and then connect it as needed. I think it would make the filtering easier after the fact.
Tuff to tell without an actual connection to the DB but maybe something like this. Also, i would alias everything because it's tuff to tell what columns are in what tables...
with temp as (
/* Setup common table expression with basically all the info we need If your
* DBMS doesn't support common table expressions (CTE's) then put this in a
* view, or a temp table? */
select
t1.id_empresa as id_empresa ,
t1.periodo as periodo ,
t2.id_delegacion as id_delegacion ,
t2.monto as monto
from
cuotasindical.pagos as t1 inner join
cuotasindical.empresa as t2 on t1.id_empresa = t2.id_empresa and t2.id_delegacion = 5
)
select
t1.id_empresa as id_empresa ,
max(t1.ultimoPeriodo) as ultimoPeriodo,
min(t2.anteriorPeriodo) as anteriorPeriodo,
sum(t3.ultimoMonto ) as ultimoMonto ,
sum(t4.anteriorMonto) as anteriorMonto
from
(select id_empresa, max(periodo) as ultimoPeriodo from temp) as t1 inner join
(select id_empresa, min(periodo) as anteriorPeriodo from temp) as t2 on t1.id_empresa = t2.id_empresa inner join
(select id_empresa, periodo, sum(monto) as ultimoMonto from temp) as t3 on t1.id_empresa = t3.id_empresa and t1.ultimoPeriodo = t3.periodo inner join
(select id_empresa, periodo, sum(monto) as anteriorMonto from temp) as t4 on t1.id_empresa = t4.id_empresa and t2.anteriorMonto = t4.periodo inner join
where
.....
group by
t1.id_empresa
having
.....