0

このクエリを取得しました:

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);

エンプレサごとに、最後の 2 つのパゴス (ピリオド順) を比較して、パーセンテージ (この場合は 10) よりも大きいか小さいかを確認する必要があります。

私は得ています

エラー コード: 1054。'where 句' の不明な列 'P1.id_empresa'

その比較がある唯一のwhere句は、制限のあるサブクエリです

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

二重サブクエリは、IN句の制限2を回避するためのものです(このリンクで取得してください)

なぜそのエラーが発生するのですか? group by の後に、having 句のサブクエリで参加できると思いました (where 句のように)

または、私が見逃しているエラーがありますか?

前もって感謝します

4

2 に答える 2

2

問題は、mysql がサブクエリで 1 つの深いレベルのスコープしか持たないことでした。

また、サブクエリの制限の問題があるので、私がしていることは

    ..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
于 2013-04-11T15:55:35.127 に答える
0

特定のエラーで、id_empresa は実際には cuotasindical.pagos の列ですか?

そうでない場合、having 句にはグループ内の何かの情報が含まれているため、オプティマイザーが混乱する可能性があると思います...「() に P1.periodo を持っている」。P1.periodo も group by です。

私が理解しているように、group byは集計ではないフィールド用です。集計ではないフィールドはどこにありますか。

持っているのは奇妙なものです...「あなたが集約したものに基づいてフィルタリングしますde">P1.periodoを集約していませんが、それが問題である場合、エラーメッセージはやや欺かれています。

データベースでサポートされている場合は、デバッグと可視性のために CTE (共通テーブル式) を確認することを検討します。(最新のMySQLについてはわかりません)。

サポートされていない場合は、ビューを使用してみてください...同じ2つのテーブルを参照するコードがかなりあります。データセットを生成し、必要に応じて接続することをお勧めします。事後のフィルタリングが容易になると思います。

DBへの実際の接続なしで伝えるタフですが、おそらくこのようなものです。また、どの列がどのテーブルにあるかを伝えるのは面倒なので、 すべてにエイリアスを付けます...

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 
    ..... 
于 2013-04-11T15:56:40.317 に答える