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

昨晚提出了这个问题,我想我的问题是:是不是太多了?我很确定还有其他方法可以在没有所有嵌套查询的情况下获得相同的结果。它可以工作,但在我的开发环境中需要一些时间,我敢打赌在生产环境中需要更多时间......任何建议? 如果您需要表格结构,请告诉我...

编辑:实际上第二个 SELECT 是最困扰我的,它与第一个完全相同,但我需要第二个结果,但是如果我尝试在第一个 SELECT 中获得第二个结果,它会给我“操作数应该包含 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 回答