[英]Mysql - Sum by other column value
這就是問題所在。 我有一個很長但不是很復雜的查詢:
SUM(x.value)
FROM valuetable AS x
LEFT JOIN jointable_1 AS y
LEFT JOIN jointable_2 AS z
etc
...
GROUP BY y.id, z.id
有 n 個左連接,我需要保持這種方式,因為新的左連接必須隨時可用。 我顯然將 n 值復制到 SUM 中,因為joinables 可以有多個結果,並且出於靈活的 WHERE 原因,我不能將它們中的任何一個分解為子查詢。 我只需要每個 x.id 一個 x.value 到 SUM 中,這也很明顯。
- 我不能將 x.id 添加到 GROUP BY,因為我需要一行來為每個 y.id 求和。
- 我不能使用計算:
SUM(x.value)*COUNT(DISTINCT x.id)/COUNT(*)
因為總和可以有任意數量的 x.values,因為不同的 x.id-s 有不同數量的連接。
- 我不能選擇 DISTINCT x.value,因為任何 x.id 都可以有任何 x.value 並且它們可以包含相同的值。
- 我不知道如何為 sum 創建子查詢,因為我不能在子查詢中使用聚合值(例如 GROUP_CONCAT(DISTINCT x.id)),或者我可以嗎?
無論如何,就是這樣。 我知道我可以重新排列查詢(子查詢而不是連接,不同於),但我想把它作為最后的手段。 有沒有辦法實現我想要的?
很抱歉,沒有子查詢(或視圖),沒有通用的方法可以做你想做的事。
一點行話:“基數”。 對於我們的目的,它是表或結果集中的行數。 (就我們而言,結果集是一種虛擬表。)
對於像SUM(col)
和COUNT(*)
這樣的聚合函數要給出好的結果,我們必須注意被匯總表的基數。 這種事
SELECT DATE(sale_time) sale_date,
store_id,
SUM(sale_amount) total_sales
FROM sale
GROUP BY DATE(sale_time), store_id
總結與基礎表相同的結果表基數,因此它生成有用的結果。
但是,如果我們這樣做
SELECT DATE(sale.sale_time) sale_date,
sale.store_id,
SUM(sale.sale_amount) total_sales,
COUNT(promo.promo_id) promos
FROM sale
LEFT JOIN promo ON sale.store_id = promo.store_id
AND DATE(sale.sale_time) = promo.promo_date
GROUP BY DATE(sale.sale_time), sale.store_id
我們破壞了匯總結果集的基數。 除非我們確定每個商店在每一天都有零個或一個促銷記錄,否則這永遠不會起作用。 為什么不? LEFT JOIN 操作會影響正在匯總的虛擬表的基數。 這意味着一些 sale_amount 值我不止一次出現在 SUM 中,因此 SUM 將不正確或不值得信賴。
如何防止 LEFT JOIN 操作弄亂您的基數? 確保您的 LEFT JOIN 的ON
子句將右側的每一行與左側的零行或一行相匹配。 也就是說,確保 JOIN 兩側的(虛擬)表具有適當的基數。
(在實體關系行話中,您的 SUM 失敗,因為您在進行求和之前加入了具有一對多關系的兩個實體。)
理論上最簡潔的方法是在連接之前執行兩個聚合操作。 這以 LEFT JOIN 是一對無或一對一的方式連接兩個虛擬表
SELECT sales.sale_date,
sales.store_id,
sales.total_sales,
promos.promo_count
FROM (
SELECT DATE(sale_time) sale_date,
store_id,
SUM(sale_amount) total_sales
FROM sale
GROUP BY DATE(sale_time), sale_store
) sales
LEFT JOIN (
SELECT store_id,
promo_date
COUNT(*) promo_count
FROM promo
GROUP BY store_id, promo_date
) promos ON sales.store_id = promos.store_id
AND sales.sale_date = promo.promo_date
盡管此 SQL 很復雜,但大多數服務器都能有效地處理這種模式。
故障排除提示:如果您在查詢的同一級別看到SUM() ... FROM ... JOIN ... GROUP BY ,則可能存在基數問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.