获取每个月的产品总销售额,空白处为 0

Posted

技术标签:

【中文标题】获取每个月的产品总销售额,空白处为 0【英文标题】:Get product total sales per moth, with 0 in the gaps 【发布时间】:2015-07-08 10:09:43 【问题描述】:

我最近遇到了一个 SQL 查询问题。我试图归档的是在商店中获取每种产品并显示每个月销售了多少。但是,有时这些产品有几个月没有售出,这意味着它们不会被展示。

例如,这是我现在得到的结果

      Article   Month  Sold
      CN140027    6     312
      CN140027    7     293
      CN140027    12    122
      CN140186    1     10
      CN140186    4     2

虽然我想得到更多这样的东西

      Article   Month  Sold
      CN140027    6     312
      CN140027    7     293
      CN140027    8     0
      CN140027    9     0
      CN140027    10    0
      CN140027    11    0
      CN140027    12    122
      CN140186    1     10
      CN140186    2     0
      CN140186    3     0
      CN140186    4     2

这是我目前正在使用的查询

SELECT k.artikelnr, Months.datefield as `Months`, IFNULL(SUM(k.menge),0) as `Quantity`
FROM store_shop_korb as k LEFT OUTER JOIN office_calendar AS Months 
ON Months.datefield = month(k.date_insert)
WHERE k.date_insert BETWEEN "2014-12-01" AND "2015-12-31"
group by k.artikelnr, Months.datefield

我错过了什么?或者我做错了什么?非常感谢任何帮助。

提前致谢。

编辑: 附加信息:

office_calendar 是日历表。它只包含作为注册表的月份,从 1 到 12。

此外,我从名为“store_shop_korb”的表中获取商品/产品 ID,该表包含已下订单的所有行(因此它包含商品 ID、价格、每个订单的数量......)

【问题讨论】:

尝试右外连接而不是左外连接。 是的,我已经尝试过左、右和内连接。我仍然得到相同的结果 您的日历表中是否实际显示了那些有间隔的月份?我们需要查看您日历表中的数据 【参考方案1】:

这对我有用:

SELECT k.artikelnr, c.datefield AS `Month`, COALESCE(s.Quantity, 0) AS Sold
FROM (
    SELECT artikelnr
    FROM store_shop_korb
    GROUP BY artikelnr
) k
JOIN office_calendar c
LEFT JOIN (
    SELECT artikelnr, MONTH(date_insert) AS monthfield, SUM(menge) AS Quantity
    FROM store_shop_korb
    GROUP BY artikelnr, MONTH(date_insert)
) s ON k.artikelnr = s.artikelnr AND c.datefield = s.monthfield
ORDER BY k.artikelnr, c.datefield

如果你有一个文章表,你可以用它来代替子查询 k。我基本上是在进行正常化。

解释:

基本上有 3 组数据加入。第一个是一组不同的文章(k),第二个是一组不同的月份(c)。这两个没有限制地连接,这意味着你得到笛卡尔积(每篇文章 x 每月)。然后将此结果左连接到每月销售额,这样我们就不会丢失 0 个条目。

【讨论】:

您认为对于不匹配的月份,此查询将获取x.artikelnr(即)article 这正是我所需要的。最后一件事:你能解释一下它是如何工作的吗?因为当有两个以上的连接时,我仍然不明白发生了什么。非常感谢,也感谢大家的回答。 我有一个问题:如果我需要超过一年的销售怎么办?例如,从 2014 年 1 月到 2015 年 6 月。 1.您需要使用包含您感兴趣的月份列表的日历 (c)(在这种情况下,可能是(年、月)对) 2. 调整每月销售额中的分组以分组年月 3. 调整join on s 为join on year 和month。 4.调整字段选择和排序以包括年和月【参考方案2】:

添加另一个 where 条件,我想它会解决你的问题

SELECT k.artikelnr, Months.datefield as `Months`, IFNULL(SUM(k.menge),0) as `Quantity`

FROM store_shop_korb as k LEFT OUTER JOIN office_calendar AS 月 ON Months.datefield = month(k.date_insert) WHERE IFNULL(SUM(k.menge),0)>0 AND k.date_insert BETWEEN "2014-12-01" AND "2015-12-31" 按 k.artikelnr、Months.datefield 分组

【讨论】:

【参考方案3】:

我已经在 MSAccess 中尝试过,它似乎可以正常工作

SELECT PRODUCT, CALENDAR.MONTH, A

FROM CALENDAR LEFT JOIN (

    SELECT PRODUCT, MONTH(SALEDTE) AS M, SUM(SALEAMOUNT) AS A
    FROM SALES 
    WHERE SALEDTE BETWEEN #1/1/2015# AND #12/31/2015#
    GROUP BY PRODUCT, MONTH(SALEDTE) ) AS X

ON X.M = CALENDAR.MONTH

【讨论】:

【参考方案4】:

如果您已经有日历表,请使用它。

SELECT B.Article,
       A.Month,
       COALESCE(c.Sold, 0)
FROM   (SELECT DISTINCT Months.datefield --Considering this as months feild
        FROM   office_calendar AS Months) A
       CROSS JOIN (SELECT DISTINCT article
                   FROM   Yourtable) B
       LEFT OUTER JOIN Yourtable C
                    ON a.month = c.Month
                       AND b.Article = c.Article 

否则,您需要一个 months 表。试试这个。

SELECT *
FROM   (SELECT 1 AS month UNION
        SELECT 2 UNION
        SELECT 3 UNION
        SELECT 4 UNION
        SELECT 5 UNION
        SELECT 6 UNION
        SELECT 7 UNION
        SELECT 8 UNION
        SELECT 9 UNION
        SELECT 10 UNION
        SELECT 11 UNION
        SELECT 12) A
       CROSS JOIN (SELECT DISTINCT article
                   FROM   Yourtable) B
       LEFT OUTER JOIN Yourtable C
                    ON a.month = c.Month
                       AND b.Article = c.Article 

【讨论】:

@Constantin - 更新 op 已经声明尝试了正确的完全连接...您的解决方案有何不同? 停止盲目评论!。检查它是否与 OP 的 Left OUTER JOIN 相同

以上是关于获取每个月的产品总销售额,空白处为 0的主要内容,如果未能解决你的问题,请参考以下文章

s-s-rS 获取之前的总数

SQL Server Management Studio 一个月的总销售额

查询给定日期 X 个月的销售总额

如何显示每个产品的总订单销售额和产品相关信息。数据库服务器 2014

精度损失而引发的 bug

oracle 分析函数5