[英]SUM of multiple rows of SUMs in MySQL
我有一個查詢,返回每個order
的total
列:
SELECT o.id, o.created, o.status, o.shipping,
SUM(op.price*op.amount*(1+op.tax/100.0))+COALESCE(o.shipping, 0)*(1+o.shipping_tax/100.0)+COALESCE(o.payment_fee, 0)*(1+o.shipping_tax/100.0) AS total
FROM orders AS o
LEFT OUTER JOIN order_products as op ON o.id=op.order_id
GROUP BY o.id;
查詢的輸出
現在,我要計算總收入,因此將是這些total
列的total
。
我嘗試使用像這樣的子查詢:
SELECT
SUM(total) FROM (
SELECT
SUM(op.price*op.amount*(1+op.tax/100.0))+COALESCE(o.shipping, 0)*(1+o.shipping_tax/100.0)+COALESCE(o.payment_fee, 0)*(1+o.shipping_tax/100.0) AS total
FROM orders AS o
LEFT OUTER JOIN order_products as op ON o.id=op.order_id
GROUP BY o.id
) AS foo
;
查詢的輸出
然而:
SUM(total)
,而不是foo
AS foo
用於子查詢,而不是頂級SUM()
AS foo
,它將無法正常工作 查詢以求和SUM的多行,應該如何看待?
注意:
這些NULL總數
幾乎肯定不會在生產中存在,但是最好使用
似乎這樣的SUM()可以使用NULL值嗎? COALESCE(x, 0)
來確保查詢正確執行。
如果您想為名稱加上別名,則必須在選擇之前而不是之后進行設置,並且要檢查是否為null,必須為此設置一個值:
SELECT
SUM(COALESCE(a.total,0)) as foo FROM (
SELECT
SUM(op.price*op.amount*(1+op.tax/100.0))+COALESCE(o.shipping, 0)*(1+o.shipping_tax/100.0)+COALESCE(o.payment_fee, 0)*(1+o.shipping_tax/100.0) AS total
FROM orders AS o
LEFT OUTER JOIN order_products as op ON o.id=op.order_id
GROUP BY o.id
) AS a
SELECT
SUM(
COALESCE(op.order_total, 0)
+COALESCE(o.shipping, 0)*(1+o.shipping_tax/100.0)
+COALESCE(o.payment_fee, 0)*(1+o.shipping_tax/100.0)
)
AS grand_total
FROM
orders AS o
LEFT OUTER JOIN
(
SELECT
order_id,
SUM(price*amount*(1+tax/100.0)) AS order_total
FROM
order_products
GROUP BY
order_id
)
AS op
ON o.id=op.order_id
編輯:
你說過:
SUM(x+y+z) / COUNT(op.order_total)
為506
AVG(x+y+z)
得到532
在我看來,這意味着當x
NOT NULL
為NULL
時,某些x+y+z
NOT NULL
,因此看來y
或z
為NULL
。
由於y
和z
為COALESCE(?, 0) * (1+o.shipping_tax/100.0)
,因此感覺 shipping_tax
有時為NULL
。
試試這個查詢...
SELECT
SUM(
COALESCE(op.order_total, 0)
+COALESCE(o.shipping, 0)*(1+o.shipping_tax/100.0)
+COALESCE(o.payment_fee, 0)*(1+o.shipping_tax/100.0)
)
AS grand_total,
AVG(
COALESCE(op.order_total, 0)
+COALESCE(o.shipping, 0)*(1+o.shipping_tax/100.0)
+COALESCE(o.payment_fee, 0)*(1+o.shipping_tax/100.0)
)
AS grand_average,
COUNT(
COALESCE(op.order_total, 0)
+COALESCE(o.shipping, 0)*(1+o.shipping_tax/100.0)
+COALESCE(o.payment_fee, 0)*(1+o.shipping_tax/100.0)
)
AS grand_row_count,
COUNT(
*
)
AS set_row_count,
COUNT(
o.shipping_tax
)
AS shipping_tax_row_count,
AVG(
COALESCE(op.order_total, 0)
+(COALESCE(o.shipping, 0)+COALESCE(o.payment_fee, 0))
*COALESCE(1+o.shipping_tax/100.0, 1)
)
AS revised_grand_average
FROM
orders AS o
LEFT OUTER JOIN
(
SELECT
order_id,
SUM(price*amount*(1+tax/100.0)) AS order_total
FROM
order_products
GROUP BY
order_id
)
AS op
ON o.id=op.order_id
我希望 ...
grand_average == grand_total / grand_row_count
set_row_count > grand_row_count
grand_row_count == shipping_tax_row_count
如果是這樣,那么revised_grand_average
應該對您有用。
如果不是,那么希望這給您一個開始調查的地方。
您不需要子查詢。 只需從原始查詢中刪除GROUP BY
:
SELECT SUM(op.price*op.amount*(1+op.tax/100.0))+COALESCE(o.shipping, 0)*(1+o.shipping_tax/100.0)+COALESCE(o.payment_fee, 0)*(1+o.shipping_tax/100.0) AS total
FROM orders o LEFT OUTER JOIN
order_products op
ON o.id = op.order_id;
這將對所有行進行計算。 它應該快於兩個級別的聚合。
結果將在稱為total
的列中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.