2016-01-23 57 views
2

我已經想出了基於特定組計算字段總數的解決方案,但看起來我很期待得到結果。 當談到sql時,我有一些基本的知識。用2個表選擇減去SUM和COUNT的最佳方法是什麼?

是否有明顯的改進,爲什麼?
爲什麼我想縮短這個:在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。

+0

你的查詢看起來很好。它是按每個維度單獨彙總(裝運和訂閱),因此這些值也應該是正確的。 –

回答

2

如果你把在線狀態並刪除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的角度來看,你的原始版本很好。

+1

謝謝,擺脫ifnull和額外的組肯定有幫助。 – arma

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

感謝您的解決方案,我選擇其他答案,因爲它刪除了一些事情,你的查詢是相同的性能方面似乎。 – arma

相關問題