用2表选择减去SUM和COUNT的最佳方法是什么?

时间:2016-01-23 14:02:04

标签: mysql sql

我已经提出了基于特定组计算字段总数的解决方案,但是达到我期望的结果看起来很长。 对于sql,我有一些基本的知识。

是否有明显的改进和原因?
为什么我想缩短它:在ORM类型系统中更容易实现。

更改方案不是一种选择。

架构和示例数据:http://sqlfiddle.com/#!9/62df6

使用以下方式查询:

SELECT s.release_id,
       (s.shipments_total - IFNULL(sh.shipment_entries, 0)) AS shipments_left
FROM
  ( SELECT release_id,
           SUM(shipments) AS shipments_total
   FROM subscriptions
   WHERE is_paid = 1
     AND shipments > 1
   GROUP BY release_id ) AS s
LEFT JOIN
  ( SELECT release_id,
           COUNT(*) AS shipment_entries
   FROM shipments
   GROUP BY release_id ) AS sh ON s.release_id = sh.release_id

样本数据的预期结果是在sqlfiddle中。

2 个答案:

答案 0 :(得分:3)

您可以将联接内联:

   SELECT s.release_id,
     SUM(s.Shipments) - IFNULL(( SELECT COUNT(*) AS shipment_entries 
                                 FROM shipments sh
                                 WHERE sh.release_id = s.release_id
                                 GROUP BY sh.release_id ), 0) AS shipments_left
   FROM subscriptions s
   WHERE is_paid = 1
     AND shipments > 1
   GROUP BY s.release_id

此执行计划也更具效果。

答案 1 :(得分:3)

如果您将条件设置为内​​嵌并删除group by,那么您就不需要ifnull()

   SELECT s.release_id,
          (SUM(s.Shipments) -
           (SELECT COUNT(*) 
            FROM shipments sh
            WHERE sh.release_id = s.release_id
           )
          ) AS shipments_left
   FROM subscriptions s
   WHERE is_paid = 1 AND shipments > 1
   GROUP BY s.release_id;

如果没有匹配,则子查询返回0,而不是NULL(使用GROUP BY,它将返回NULL)。我不确定你的ORM模型是否更容易。从SQL的角度来看,您的原始版本很好。