1
SELECT 
productos.prod_id,
productos.prod_codigo1,
productos.prod_descripcion,
(SELECT SUM(cotdetalle.cotd_cantidad)
    FROM cotdetalle
    WHERE cotdetalle.cotd_codigo = productos.prod_codigo1
    AND cotdetalle.cotd_cote_id IN(
            SELECT cotencabezado.cote_id
            FROM cotencabezado
            WHERE cotencabezado.cote_status = 'cerrada'
            AND MONTH(cotencabezado.cote_cierre) = MONTH(NOW()) AND YEAR(cotencabezado.cote_cierre) = YEAR(NOW())
    )
) AS cuantos,
(SELECT SUM(cotdetalle.cotd_cantidad * cotdetalle.cotd_precio)
    FROM cotdetalle
    WHERE cotdetalle.cotd_codigo = productos.prod_codigo1
    AND cotdetalle.cotd_cote_id IN(
            SELECT cotencabezado.cote_id
            FROM cotencabezado
            WHERE cotencabezado.cote_status = 'cerrada'
            AND MONTH(cotencabezado.cote_cierre) = MONTH(NOW()) AND YEAR(cotencabezado.cote_cierre) = YEAR(NOW())
    )
) AS monto
FROM productos
ORDER BY monto DESC
LIMIT 0, 50

昨夜、このクエリが出てきました。私の質問は、多すぎますか? ネストされたクエリをすべて使用せずに同じ結果を得る方法は他にもあると確信しています..動作しますが、開発環境では時間がかかります.本番環境ではもっと時間がかかると思います...任意の提案? テーブル構造が必要な場合はお知らせください...

編集:実際には、その 2 番目の SELECT が最も気になります。最初の SELECT とまったく同じですが、2 番目の結果が必要ですが、最初の SELECT で 2 番目の結果を取得しようとすると、「オペランドには 1 を含める必要があります。列」エラー...

もう少し情報: monto、cuantos、productos.prod_codigo1、productos.prod_descripcion で注文できるようにする必要があります。

sqlfiddle.com の例: http://sqlfiddle.com/#!2/c4391/1

4

3 に答える 3

2

これは、次の方法でグループとの単純な結合として行う必要があります。

SELECT p.prod_id, p.prod_codigo1, p.prod_descripcion,
       t.quantos, t.monto
FROM productos p left outer join
     (SELECT cotdetalle.cotd_codigo, SUM(cotdetalle.cotd_cantidad) as quantos,
             SUM(cotdetalle.cotd_cantidad * cotdetalle.cotd_precio) as monto
      FROM cotdetalle
      WHERE cotdetalle.cotd_codigo = productos.prod_codigo1 and
            cotdetalle.cotd_cote_id IN
                (SELECT cotencabezado.cote_id
                 FROM cotencabezado
                 WHERE cotencabezado.cote_status = 'cerrada' and
                       MONTH(cotencabezado.cote_cierre) = MONTH(NOW()) AND 
                       YEAR(cotencabezado.cote_cierre) = YEAR(NOW()
               )
      group by cotdetalle.cotd_codigo
    ) t
    on t.cotd_codigo = p.prod_codigo1
ORDER BY monto DESC
LIMIT 0, 50

これは物事を改善するはずです。ただし、MySQL は IN とサブクエリをうまく処理できません。したがって、サブクエリの "IN" の代わりに、それを結合に変更します。サブクエリに「distinct」が追加されていることに注意してください。これは IN には必要ありませんが、結合用です。

SELECT p.prod_id, p.prod_codigo1, p.prod_descripcion,
       t.quantos, t.monto
FROM productos p join
     (SELECT cd.cotd_codigo, SUM(cd.cotd_cantidad) as quantos,
             SUM(cd.cotd_cantidad * cd.cotd_precio) as monto
      FROM cotdetalle cd join
           (SELECT distinct cc.cote_id
            FROM cotencabezado cc
            WHERE cc.cote_status = 'cerrada' and
                  MONTH(cc.cote_cierre) = MONTH(NOW()) AND 
                  YEAR(cc.cote_cierre) = YEAR(NOW()
           ) cc
           on cd.cotd_cote_id = cc.cote_id
      group by cd.cotd_codigo
    ) t
    on t.cotd_codigo = p.prod_codigo1
ORDER BY monto DESC
LIMIT 0, 50

これを SQL Fiddle でテストしていないため、構文エラーがある可能性があります。

于 2012-08-20T00:36:15.440 に答える
1

ステートメントを次のように単純化しないのはなぜですか

SELECT productos.prod_id,
productos.prod_codigo1,
productos.prod_descripcion,
( SELECT SUM(cotdetalle.cotd_cantidad) AS cuantos,
         SUM(cotdetalle.cotd_cantidad * cotdetalle.cotd_precio) AS monto
  FROM cotdetalle
  WHERE cotdetalle.cotd_codigo = productos.prod_codigo1
  AND cotdetalle.cotd_cote_id IN( SELECT cotencabezado.cote_id
                                  FROM cotencabezado
                                  WHERE cotencabezado.cote_status = 'cerrada'
                                  AND MONTH(cotencabezado.cote_cierre) = MONTH(NOW())
                                  AND YEAR(cotencabezado.cote_cierre) = YEAR(NOW())
                                 )
)
FROM productos 
ORDER BY monto DESC
LIMIT 0, 50
于 2012-08-19T20:13:29.457 に答える
0

わかりました、それはこのように終わりました:

SELECT p.prod_id, p.prod_codigo1, p.prod_descripcion, t.cuantos, t.monto
FROM productos AS p
LEFT JOIN(
    SELECT cd.cotd_codigo,
    SUM(cd.cotd_cantidad) AS cuantos,
    SUM(cd.cotd_cantidad * cd.cotd_precio) AS monto
    FROM cotdetalle AS cd
    JOIN(
        SELECT DISTINCT ce.cote_id
        FROM cotencabezado AS ce
        WHERE ce.cote_status = 'cerrada'
        AND MONTH(ce.cote_cierre) = MONTH(NOW())
        AND YEAR(ce.cote_cierre) = YEAR(NOW())
    ) AS ce
    ON cd.cotd_cote_id = ce.cote_id
    GROUP BY cd.cotd_codigo
) AS t
ON cd.cotd_codigo = p.prod_codigo1
ORDER BY monto DESC
LIMIT 0, 50

これは、Gordon Linoffの提案に基づいているため、はるかにうまく機能します。ありがとうございます。

于 2012-08-21T04:30:33.300 に答える