簡體   English   中英

MySQL中SUM的多行總和

[英]SUM of multiple rows of SUMs in MySQL

我有一個查詢,返回每個ordertotal列:

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 ,它將無法正常工作
  • 該查詢返回的結果可能不正確, 但這可能是由於rounding引起的

查詢以求和SUM的多行,應該如何看待?

注意: 這些NULL總數 幾乎肯定不會在生產中存在,但是最好使用 COALESCE(x, 0)來確保查詢正確執行。 似乎這樣的SUM()可以使用NULL值嗎?

如果您想為名稱加上別名,則必須在選擇之前而不是之后進行設置,並且要檢查是否為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 NULLNULL時,某些x+y+z NOT NULL ,因此看來yzNULL

由於yzCOALESCE(?, 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM