【问题标题】:MySQL showing sum 0MySQL 显示总和 0
【发布时间】:2013-03-28 09:43:45
【问题描述】:

所以我有一个包含一组订单项目的表,订单项目表跟踪特定订单中包含的特定项目的数量。下面是本示例中使用的表格的简化版本。

订单商品表

order_item_id : int
order_item_item_id : int
order_item_quantity : int
order_item_order_id : int

订单表

order_id : int
order_date : date

我正在尝试执行单个查询,该查询将平均每周、每月和所有时间特定 order_item_item_id 的销售额。

目前我的查询如下

SELECT totalAvg.item 

ROUND(AVG(totalAvg.total)+0.4999999, 0) AS totalAverage,  
ROUND(AVG(monthAvg.total)+0.4999999, 0) AS monthAverage, 
ROUND(AVG(weekAvg.total)+0.4999999, 0) AS weekAverage from

(SELECT orderitem.order_item_item_id AS item, SUM(orderitem.order_item_quantity) AS total,
 DATE(`order`.order_date) AS date FROM orderitem, `order` WHERE orderitem.order_item_order_id = 
`order`.order_id GROUP BY DATE(`order`.order_date), order_item_item_id) AS totalAvg,

(SELECT orderitem.order_item_item_id AS item, SUM(orderitem.order_item_quantity) AS total, 
DATE(`order`.order_date) AS date FROM orderitem, `order` WHERE orderitem.order_item_order_id =
`order`.order_id AND `order`.order_date > date_sub(now(), interval 1 week) GROUP BY 
DATE(`order`.order_date), order_item_item_id) AS weekAvg,

(SELECT orderitem.order_item_item_id AS item, SUM(orderitem.order_item_quantity) AS total,
DATE(`order`.order_date) AS date FROM orderitem, `order` WHERE orderitem.order_item_order_id = 
`order`.order_id AND `order`.order_date > date_sub(now(), interval 1 month) GROUP BY 
DATE(`order`.order_date), order_item_item_id) AS monthAvg,

WHERE totalAvg.item = monthAvg.item AND
monthAvg.item = weekAvg.item 
GROUP BY item

这样做的问题是,如果 weekAvg 表中不存在某个项目,则不会为 totalAvg 或 monthAvg 打印任何结果。我怎样才能在单个语句中执行此操作?

样本数据

{order_id : 5, order_date : 02/02/2013}
{order_id : 6, order_date : 13/03/2013}

{order_item_id : 1, order_item_order_id : 5, order_item_item_id : 1, order_item_quantity : 3}
{order_item_id : 2, order_item_order_id : 6, order_item_item_id : 1, order_item_quantity : 4}

当前输出不会返回任何内容,因为每周报告没有 id 为 1 的订单项的条目。我正在尝试解决这个问题,以便它输出以下内容

totalAverage = 3.5
monthAverage = 4
weekAverage = 0

数值计算如下:

总平均数 = 特定商品的售出总数除以该商品的售出天数。

月和周值与之前的计算相同,但有时间限制,因此订单必须在上周/月内下达。

【问题讨论】:

    标签: mysql


    【解决方案1】:

    您需要使用outer joins 将totalAvg 连接到monthAvg 和weekAvg。您可以使用 COALESCE() 来确保您得到 0 而不是 NULL 来表示空的周或月值。

    您还应该使用 ANSI 连接语法。它更不容易出错并且更易读。

    试试这样的:

    SELECT totalAvg.item,
    ROUND(AVG(totalAvg.total)+0.4999999, 0) AS totalAverage,  
    COALESCE(ROUND(AVG(monthAvg.total)+0.4999999, 0),0) AS monthAverage, 
    COALESCE(ROUND(AVG(weekAvg.total)+0.4999999, 0),) AS weekAverage 
    from
    (
      SELECT orderitem.order_item_item_id AS item, 
        SUM(orderitem.order_item_quantity) AS total,
        DATE(`order`.order_date) AS date 
      FROM orderitem
        inner join `order` on orderitem.order_item_order_id = `order`.order_id 
      GROUP BY DATE(`order`.order_date), order_item_item_id
    ) AS totalAvg
    left outer join
    (
      SELECT orderitem.order_item_item_id AS item, 
        SUM(orderitem.order_item_quantity) AS total, 
        DATE(`order`.order_date) AS date 
      FROM orderitem
        inner join `order` on orderitem.order_item_order_id = `order`.order_id 
      WHERE `order`.order_date > date_sub(now(), interval 1 week) 
      GROUP BY 
      DATE(`order`.order_date), order_item_item_id
    ) AS weekAvg on weekAvg.item = totalAvg.item
    left outer join
    (
      SELECT orderitem.order_item_item_id AS item, 
        SUM(orderitem.order_item_quantity) AS total,
        DATE(`order`.order_date) AS date 
      FROM orderitem
        inner join `order` on orderitem.order_item_order_id = `order`.order_id 
      WHERE `order`.order_date > date_sub(now(), interval 1 month) 
      GROUP BY DATE(`order`.order_date), order_item_item_id
    ) AS monthAvg on monthAvg.item = totalAvg.item
    GROUP BY item
    

    【讨论】:

    • 我想我很困惑,可能是因为我选择了一个臃肿(尽管被缩减)的例子。现在我正试图将它放入实际版本并试图弄清楚你做了什么但无法让它工作。您能否在解释它的作用/工作原理的同时展示一个合并、内连接和左外连接的示例?我一生都无法解决,这至少可以说是非常令人沮丧的:P
    猜你喜欢
    • 1970-01-01
    • 2013-07-01
    • 2021-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多