B1查询|不同时间段即 1 / 3 / 6 / 12 个月的月销售额合并

问题描述

真的很纠结这个。寻找一种查询不同时间跨度的销售量的方法,所有这些都放在一个表中。

假设现在是 8 月 13 日。然后我想总结以下销售量:

  • 7 月 1 日 00:00:00 - 7 月 31 日 11:59:59(过去 1 个月)
  • 5 月 - 1 日 00:00:00 - 7 月 31 日 11:59:59(过去 3 个月)
  • 2 月 1 日 00:00:00 - 7 月 31 日 11:59:59(过去 6 个月)
  • 8 月 1 日 00:00:00 - 7 月 31 日 11:59:59(过去 12 个月)

我尝试重用数据透视查询示例中的片段,这些片段可以找到与销售量相关但没有成功。 我从头开始,首先尝试创建可用于时间跨度的日期时间,但这已经非常繁琐,而且不知何故感觉不对。

我认为我需要以 4 个单独的查询结束,然后需要将这些查询连接起来以将所有列合并到一个表中:

物品名称 项目代码 Sal.vol 1 月 Sal.vol 3 个月 Sal.vol 6 个月 Sal.vol 12 个月
项目 1 10102251 10 30 60 120
项目 2 10120101 14 35 78 181

我目前的进展:

SELECT
  T1.itemcode,month(T1.[docDate]) as month,T3.ItemName,SUM(t1.quantity )
FROM INV1 T1 INNER JOIN OINV T2 ON T1.docentry = T2.docentry INNER JOIN OITM T3 ON T1.ItemCode = T3.ItemCode
WHERE T1.[docDate] between DATEADD(month,-4,GETDATE()) and DATEADD(month,-1,GETDATE()) AND T1.ItemCode LIKE '1%' AND T3.ItmsGrpCod = 100
Group By  T1.itemcode,month(T1.[docDate])

对于我的约会时间,我想按如下方式构建它们:

DECLARE @date date = month(DATEADD(month,GETDATE())) + '-01-' + year(DATEADD(month,GETDATE()));
DECLARE @datetime datetime = @date;     
SELECT @datetime AS '@datetime'

但是我还没有成功,因为我在 int 到日期转换方面遇到了麻烦,我认为 Jan-Sep 的月份()将不起作用,因为它只返回 1 位数字...

有人能帮我指出正确的方向吗?

提前致谢!


更新 1:

@imerd 为我指明了正确的方向。我能够根据需要构建我的查询。分享我的中间结果,因为这现在有效。 Query 需要一些清理和优化,重复出现的主要部分外包到第二个函数中。

create function MonthFirst (@period integer ) returns date
as begin
declare @returnperiod date 
set @returnperiod = cast(cast(year(DATEADD(month,@period,GETDATE())) as varchar(4)) + '-' +
    cast(month(DATEADD(month,GETDATE())) as varchar(2)) + '-01' as date)
 return @returnperiod
end
-- drop function dbo.MonthFirst

SELECT S12.ItemCode,o1.ItemName,S12.[last 12 months],S6.[last 6 months],S3.[last 3 months],S1.[last month] FROM 
(SELECT
   T1.itemcode,CAST(SUM(t1.quantity) AS int) AS 'last 12 months'
FROM DLN1 T1 INNER JOIN ODLN T2 ON T1.docentry = T2.docentry INNER JOIN OITM T3 ON T1.ItemCode = T3.ItemCode
WHERE T1.[docDate] between CAST(dbo.MonthFirst(-12) AS datetime) AND  DATEADD(second,CAST(dbo.MonthFirst(0) AS datetime)) 
      AND T3.validFor = 'Y' AND T3.ItmsGrpCod = 100 --products / 102 raw materials
      AND T2.CANCELED = 'N'
Group By T1.itemcode) S12

FULL JOIN 

(SELECT
   T1.itemcode,CAST(SUM(t1.quantity) AS int) AS 'last 6 months'
FROM DLN1 T1 INNER JOIN ODLN T2 ON T1.docentry = T2.docentry INNER JOIN OITM T3 ON T1.ItemCode = T3.ItemCode
WHERE T1.[docDate] between CAST(dbo.MonthFirst(-6) AS datetime) AND  DATEADD(second,CAST(dbo.MonthFirst(0) AS datetime)) 
      AND T3.validFor = 'Y' AND T3.ItmsGrpCod = 100 --products / 102 raw materials
      AND T2.CANCELED = 'N'
Group By T1.itemcode) S6 on S12.ItemCode = S6.ItemCode

FULL JOIN 

(SELECT
   T1.itemcode,CAST(SUM(t1.quantity) AS int) AS 'last 3 months'
FROM DLN1 T1 INNER JOIN ODLN T2 ON T1.docentry = T2.docentry INNER JOIN OITM T3 ON T1.ItemCode = T3.ItemCode
WHERE T1.[docDate] between CAST(dbo.MonthFirst(-3) AS datetime) AND  DATEADD(second,CAST(dbo.MonthFirst(0) AS datetime)) 
      AND T3.validFor = 'Y' AND T3.ItmsGrpCod = 100 --products / 102 raw materials
      AND T2.CANCELED = 'N'
Group By T1.itemcode) S3 on S12.ItemCode = S3.ItemCode

FULL JOIN 

(SELECT
   T1.itemcode,CAST(SUM(t1.quantity) AS int) AS 'last month'
FROM DLN1 T1 INNER JOIN ODLN T2 ON T1.docentry = T2.docentry INNER JOIN OITM T3 ON T1.ItemCode = T3.ItemCode
WHERE T1.[docDate] between CAST(dbo.MonthFirst(-1) AS datetime) AND  DATEADD(second,CAST(dbo.MonthFirst(0) AS datetime)) 
      AND T3.validFor = 'Y' AND T3.ItmsGrpCod = 100 --products / 102 raw materials
      AND T2.CANCELED = 'N'
Group By T1.itemcode) S1 on S12.ItemCode = S1.ItemCode

INNER JOIN OITM o1 on S12.ItemCode = o1.ItemCode

ORDER BY o1.ItemName

更新 2:

我现在结合了来自@imerd 和@Gordon Linoff 的建议/提示,得到了这个漂亮的小查询,这几乎正是我想要的。

非常感谢!

这是我的解决方案:

DECLARE @period integer = -12
DECLARE @startperiod date
DECLARE @endperiod date 
SET @startperiod = CAST(cast(year(DATEADD(month,GETDATE())) AS varchar(4)) + '-' +
    cast(month(DATEADD(month,GETDATE())) AS varchar(2)) + '-01' AS date)
SET @endperiod = CAST(cast(year(DATEADD(month,GETDATE())) AS varchar(2)) + '-01' AS datetime)

SELECT T1.ItemCode,sum(case when datediff(month,T1.[docDate],GETDATE()) <= 12 then t1.quantity else 0 end) as month_12,GETDATE()) <= 6 then t1.quantity else 0 end) as month_6,GETDATE()) <= 3 then t1.quantity else 0 end) as month_3,GETDATE()) = 1 then t1.quantity else 0 end) as month_1
FROM DLN1 T1 INNER JOIN ODLN T2 ON T1.docentry = T2.docentry INNER JOIN OITM T3 ON T1.ItemCode = T3.ItemCode
WHERE T1.[docDate] between CAST(@startperiod AS datetime) AND  DATEADD(second,CAST(@endperiod AS datetime)) 
      AND T3.validFor = 'Y' AND T3.ItmsGrpCod = 100 --products / 102 raw materials
      AND T2.CANCELED = 'N'
GROUP BY T1.ItemCode,T3.ItemName
ORDER BY T3.ItemName ASC

@Gordon Linoff: '=' 需要是 '

再次感谢您的快速帮助!

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)