Mysql 按部件划分的销售和交易总额,按过去24个月分组

Mysql 按部件划分的销售和交易总额,按过去24个月分组,mysql,Mysql,上面的sql返回当前月份的所有零件号、销售总数(需求)和零件参与的事务总数(调用) 我们的供应商需要的是每个零件的这些信息,但在过去的24个月中,每个零件都需要分组。他们请求的csv如下所示(如果仅查看过去3个月): 意识到他们希望在过去24个月内延长这一期限。Demand1/Call1始终为当前月份 我使用WHERE/BETWEEN语句来显示日期的来源,并演示如何获得当月零件的准确报告 我不知道该怎么做的是满足需求并打24个月的电话。这是供应商希望数据采用的格式。这不是我的选择。如有任何帮助,

上面的sql返回当前月份的所有零件号、销售总数(需求)和零件参与的事务总数(调用)

我们的供应商需要的是每个零件的这些信息,但在过去的24个月中,每个零件都需要分组。他们请求的csv如下所示(如果仅查看过去3个月):

意识到他们希望在过去24个月内延长这一期限。Demand1/Call1始终为当前月份

我使用WHERE/BETWEEN语句来显示日期的来源,并演示如何获得当月零件的准确报告

我不知道该怎么做的是满足需求并打24个月的电话。这是供应商希望数据采用的格式。这不是我的选择。如有任何帮助,如能如期完成,我们将不胜感激

谢谢

编辑

我删除了sql server标记。很抱歉。这只是MySQL

另外,我在下面添加我的回复


查看DATEDIFF、TIMESTAMPDIFF,甚至PERIOD_DIFF。但实际上似乎都没有返回我需要的内容。需要做的是,第一个需求列应该搜索当前月份的第1天(含)到下个月的第1天(不含)。下一个需求列应搜索当前月份-一个月,第1天(含)到下个月-一个月,第1天(不含)。随后的每一列都应该搜索相同的参数,每列减去一个月。我不认为仅仅使用DATEDIFF就可以精确地实现这一点

我希望这是有道理的


再次感谢您的帮助。

如果我正确理解了您的问题,您可以这样做:

Part# | Demand1 | Demand2 | Demand3 | Call1 | Call2 | Call3
123   |       0 |       2 |       0 |     0 |     1 |     0
345   |       6 |       3 |       4 |     1 |     2 |     3

Part# 123: 0 transactions this month (Call1) 0 quantity sold (Demand1)
       1 transaction last month (Call2) 2 quantity sold (Demand2).
       0 transactions two months ago (Call3) 0 quantity sold (Demand3).

Part# 345: 1 transaction this month (Call1) for qty sold of 6 (Demand1)
       2 transactions last month (Call2) for qty sold of 3 (Demand2)
       3 transactions two months ago (Call3) for qty sold of 4 (Demand3)
选择
帕特纳姆探长,
金额(当库存发票日期>=dateadd(月-3,@currMonth)和库存发票日期=dateadd(月-2,@currMonth)和库存发票日期='2015-11-01 00:00:00'和库存发票日期<'2015-12-01'
按partNum分组

这将使用一个具有当前月份开始日期的变量来简化SQL。我还更改了where子句,您真的应该将>=+<与日期一起使用,而不是在日期之间使用。

这可能会让您开始Pivot查询

SELECT 
  det.partNum,
  SUM(case when inv.invoice_date >= dateadd(month, -3, @currMonth) and inv.invoice_date < dateadd(month, -2, @currMonth) then det.quantity else 0) AS Demand1,
  SUM(case when inv.invoice_date >= dateadd(month, -2, @currMonth) and inv.invoice_date < dateadd(month, -1, @currMonth) then det.quantity else 0) AS Demand2,
...
FROM details det

JOIN invoice inv ON det.invoice_id = inv.id
WHERE 
  inv.invoice_date >= '2015-11-01 00:00:00' AND inv.invoice_date < '2015-12-01'

GROUP BY partNum
如果这太令人困惑,可以使用CASE方法。不过,我会做的和另一个答案有点不同

;WITH cte AS 
(
    SELECT  det.partNum,
            SUM(det.quantity) AS DemandSum,
            COUNT(det.partNum) AS CallCount,
            DATEDIFF(MONTH,inv.invoice_date, GETDATE()) + 1 MonthDiff
    FROM    details det
            JOIN invoice inv ON det.invoice_id = inv.id
    GROUP BY det.partNum, DATEDIFF(MONTH,inv.invoice_date, GETDATE()) + 1

)
SELECT t.partNum,
       [Demand1],[Demand2],[Demand3],[Demand4],[Demand5],[Demand6],[Demand7],[Demand8],[Demand9],[Demand10],[Demand11],[Demand12],
       [Demand13],[Demand14],[Demand15],[Demand16],[Demand17],[Demand18],[Demand19],[Demand20],[Demand21],[Demand22],[Demand23],[Demand24],
       [Call1],[Call2],[Call3],[Call4],[Call5],[Call6],[Call7],[Call8],[Call9],[Call10],[Call11],[Call12],
       [Call13],[Call14],[Call15],[Call16],[Call17],[Call18],[Call19],[Call20],[Call21],[Call22],[Call23],[Call24]
FROM (SELECT DISTINCT partNum FROM cte) t
LEFT JOIN (
        SELECT * FROM (
            SELECT partNum, DemandSum, CONCAT('Demand',MonthDiff) ColName FROM cte
        ) c PIVOT (SUM(DemandSum) FOR ColName IN ([Demand1],[Demand2],[Demand3],[Demand4],[Demand5],[Demand6],[Demand7],[Demand8],[Demand9],[Demand10],[Demand11],[Demand12],
                                                [Demand13],[Demand14],[Demand15],[Demand16],[Demand17],[Demand18],[Demand19],[Demand20],[Demand21],[Demand22],[Demand23],[Demand24])    
        ) p
    ) ds ON ds.partNum = t.partNum
LEFT JOIN (
        SELECT * FROM (
            SELECT partNum, CallCount, CONCAT('Call',MonthDiff) ColName FROM cte
        ) c PIVOT (COUNT(CallCount) FOR ColName IN ([Call1],[Call2],[Call3],[Call4],[Call5],[Call6],[Call7],[Call8],[Call9],[Call10],[Call11],[Call12],
                                                [Call13],[Call14],[Call15],[Call16],[Call17],[Call18],[Call19],[Call20],[Call21],[Call22],[Call23],[Call24])    
        ) p
    ) cc ON cc.partNum = t.partNum

你可以在这里得到全部24个月的完整脚本

你能简单地按年+月分组吗?我建议按零件号、年和月分组,然后通过pivot以供应商要求的形状获取数据。我需要按零件号收集所有信息。每个零件号将有48列。我不知道如何通过按年+月分组来实现这一点。Mat,我将搜索数据透视,但在我这样做的同时,您能否提供一些类型的示例?谢谢您的快速回复。既然我们没有过滤掉当月的记录,那么WHERE子句是必要的吗?我只是把它放在原始示例中,以显示当前月份的可接受范围。我在第3行得到一个语法错误。此外,这不会为调用提供任何列。我不仅需要合计销售额,还需要计算销售次数。感谢您的帮助,但我在运行该语句时,在调用本机函数“DATEDIFF”时得到了#1582-错误的参数计数。您已经标记了mysql和sql server。。我假设由于这个错误,您只使用mysqlI,因此能够在不使用MONTH参数的情况下运行该语句,并将GETDATE更改为CURDATE。但是它没有在需求/呼叫栏中返回每月总数。JamieD77,非常抱歉。是的,只有MySQL。查看DATEDIFF、TIMESTAMPDIFF,甚至PERIOD_DIFF。但实际上似乎没有返回我需要的内容。需要做的是,第一个需求列应该搜索当前月份的第1天(含)到下个月的第1天(不含)。下一个需求列应搜索当前月份-一个月,第1天(含)到下个月-一个月,第1天(不含)。随后的每一列都应该搜索相同的参数,每列减去一个月。我不认为仅仅使用DATEDIFF就可以精确地实现这一点。
;WITH cte AS 
(
    SELECT  det.partNum,
            SUM(det.quantity) AS DemandSum,
            COUNT(det.partNum) AS CallCount,
            DATEDIFF(MONTH,inv.invoice_date, GETDATE()) + 1 MonthDiff
    FROM    details det
            JOIN invoice inv ON det.invoice_id = inv.id
    GROUP BY det.partNum, DATEDIFF(MONTH,inv.invoice_date, GETDATE()) + 1

)
SELECT t.partNum,
       [Demand1],[Demand2],[Demand3],[Demand4],[Demand5],[Demand6],[Demand7],[Demand8],[Demand9],[Demand10],[Demand11],[Demand12],
       [Demand13],[Demand14],[Demand15],[Demand16],[Demand17],[Demand18],[Demand19],[Demand20],[Demand21],[Demand22],[Demand23],[Demand24],
       [Call1],[Call2],[Call3],[Call4],[Call5],[Call6],[Call7],[Call8],[Call9],[Call10],[Call11],[Call12],
       [Call13],[Call14],[Call15],[Call16],[Call17],[Call18],[Call19],[Call20],[Call21],[Call22],[Call23],[Call24]
FROM (SELECT DISTINCT partNum FROM cte) t
LEFT JOIN (
        SELECT * FROM (
            SELECT partNum, DemandSum, CONCAT('Demand',MonthDiff) ColName FROM cte
        ) c PIVOT (SUM(DemandSum) FOR ColName IN ([Demand1],[Demand2],[Demand3],[Demand4],[Demand5],[Demand6],[Demand7],[Demand8],[Demand9],[Demand10],[Demand11],[Demand12],
                                                [Demand13],[Demand14],[Demand15],[Demand16],[Demand17],[Demand18],[Demand19],[Demand20],[Demand21],[Demand22],[Demand23],[Demand24])    
        ) p
    ) ds ON ds.partNum = t.partNum
LEFT JOIN (
        SELECT * FROM (
            SELECT partNum, CallCount, CONCAT('Call',MonthDiff) ColName FROM cte
        ) c PIVOT (COUNT(CallCount) FOR ColName IN ([Call1],[Call2],[Call3],[Call4],[Call5],[Call6],[Call7],[Call8],[Call9],[Call10],[Call11],[Call12],
                                                [Call13],[Call14],[Call15],[Call16],[Call17],[Call18],[Call19],[Call20],[Call21],[Call22],[Call23],[Call24])    
        ) p
    ) cc ON cc.partNum = t.partNum
SELECT 
    det.partNum,
    SUM(case WHEN DATEDIFF(MONTH, inv.invoice_date, GETDATE()) = 0 then det.quantity else 0 end) AS Demand1,
    SUM(case WHEN DATEDIFF(MONTH, inv.invoice_date, GETDATE()) = 1 then det.quantity else 0 end) AS Demand2,
    SUM(case WHEN DATEDIFF(MONTH, inv.invoice_date, GETDATE()) = 2 then det.quantity else 0 end) AS Demand3,
    COUNT(case WHEN DATEDIFF(MONTH, inv.invoice_date, GETDATE()) = 0 then det.partNum end) AS Call1,
    COUNT(case WHEN DATEDIFF(MONTH, inv.invoice_date, GETDATE()) = 1 then det.partNum end) AS Call2,
    COUNT(case WHEN DATEDIFF(MONTH, inv.invoice_date, GETDATE()) = 2 then det.partNum end) AS Call3
FROM 
    details det
    JOIN invoice inv ON det.invoice_id = inv.id
GROUP BY 
    det.partNum