Question

got this query:

select 
T.id_empresa, max(periodo) as ultimoPeriodo, ( 
                        select sum(monto) from cuotasindical.pagos
                        where id_empresa = T.id_empresa and periodo = max(T.periodo)
                       ) as ultimoMonto, 
min(periodo) as periodoAnterior, (
                  select sum(monto) from cuotasindical.pagos
                  where id_empresa = T.id_empresa and periodo = min(T.periodo)
                   ) as anteriorMonto
from 
  (
    select 
    P1.id_empresa, P1.periodo, sum(monto) as monto
    from cuotasindical.pagos P1
    where P1.id_empresa in (select id_empresa from cuotasindical.empresa where id_delegacion = 5)
    group by P1.id_empresa, P1.periodo
    having P1.periodo in (
                select * from (
                                select periodo
                                from cuotasindical.pagos  
                                where P1.id_empresa = id_empresa order by periodo desc limit 2
                            ) as L
               )
    and count(distinct P1.periodo) > 1
  ) T
group by id_empresa
having (abs(max(monto) - min(monto))*100/
                    (
                      select sum(monto) from cuotasindical.pagos T2
                      where T2.id_empresa = id_empresa and T2.periodo = max(periodo)
                    ) > 10);

need to compare, for each empresa, the last two pagos (ordered by periodo) to see if they have a difference bigger or smaller than a percentage (in this case, 10)

I'm getting

Error Code: 1054. Unknown column 'P1.id_empresa' in 'where clause'

the only where clause there with that comparison, is the subquery with the limit

having P1.periodo in (
                select * from (
        select periodo
        from cuotasindical.pagos  
        where P1.id_empresa = id_empresa 
        order by periodo desc limit 2
        ) as L
               )
    and count(distinct P1.periodo) > 1

the double subquery is for avoid the limit 2 in the IN clause (get that on this link)

why I'm getting that error ? I thought that I can join after the group by in a subquery in having clause (just like a where clause)

or there is an error that I'm missing?

thanks in advance

Was it helpful?

Solution

the problem was that mysql has only one deep level of scope in subquerys.

Also I have the problem of limit on subquery, so, what I do was

    ..having P1.periodo in 
    (
       select max(periodo) as periodo
       from cuotasindical.pagos H
       where P1.id_empresa = id_empresa 
    ) OR
    P1.periodo in (
       select max(periodo) as periodo
       from cuotasindical.pagos H
       where P1.id_empresa = id_empresa and periodo != P1.periodo
    )
and count(distinct P1.periodo) > 1

OTHER TIPS

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 
    ..... 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top