繁体   English   中英

SQL查询以获取过去17周中按周分组的数据

[英]SQL query to get the data grouped by weeks for the last 17 weeks

在SQL Server 2012中,我们试图按过去17周的每周分组。

输入数据

 OrderDate  OrderValue
 ----------------------
  7/17/11       10
  7/24/11       20
  7/31/11       30
   8/7/11       40

SQL对此进行了尝试:我不确定它是否朝着正确的方向发展。

Select  
    om.OrderDate, SUM(MOrderQty * MPrice) as OrderValue 
from 
    OrdMaster om 
inner join 
    OrdDetail od on om.SalesOrder = od.SalesOrder 
where
    om.OrderDate >= DATEADD(WEEK, -17,getdate()) 
group by 
    om.OrderDate

输出数据:

OrderValue   7/17/11     7/24/11     7/31/11     8/7/11  8/14/11     8/21/11     8/28/11     9/4/11  9/11/11    9/18/11  9/25/11     10/2/11     10/9/11     10/16/11    10/23/11    10/30/11    11/6/11    

任何帮助,将不胜感激! 提前致谢 !

首先,我建议如果两个表上都没有以下索引,请考虑添加它们以支持我们准备做的事情以及更多。

--===== If you don't already have them, consider adding these indexes
 CREATE NONCLUSTERED INDEX By_OrderDate
     ON [dbo].OrdMaster([OrderDate])
INCLUDE ([SalesOrder])
;
 CREATE NONCLUSTERED INDEX By_SalesOrder
     ON dbo.OrdDetail([SalesOrder])
INCLUDE ([MOrderQty],[MPrice])
;

为了使这一切“自动魔术”,我们必须使用一些动态SQL。 它称为“预聚合动态CROSSTAB”,它比大多数PIVOT运算符要快。 它使您不必每周都要接触代码,而且速度很快。 我还随意添加了“总计”列。 详细信息在代码中。

我还使用“标记化”动态SQL来简化代码编写。 它不一定是SQL注入证明(必须大量使用QUOTENAME),但由于要转换的数据类型在这里没有机会。

而且,是的,这为您提供了所需的“水平格式”。

--=======================================================================================
--      Builds and executes a high performance, pre-aggregated CROSS TAB that will
--      return the previous 17 weeks without having to adjust the code no matter
--      what today's date is. It also returns a total for the 17 weeks.
--
--      Note that if any give week has no sales, then you'll have bigger things to
--      worry about other than this code won't pick up that missing week. ;-) 
--      We could fix that but it's not worth it because it shouldn't ever happen.
--=======================================================================================
--===== If the pre-aggregate table already exists, drop it to make reruns in SSMS easier.
     IF OBJECT_ID('tempdb..#PreAgg','U') IS NOT NULL
        DROP TABLE #PreAgg
;
--===== Pre-aggregate the data into a working table.
     -- The right indexes will make this very fast and it greatly reduces the amount of
     -- work the CROSSTAB will have to do.
 SELECT  WeekDate       = CAST(DATEADD(dd,DATEDIFF(dd,-1,om.OrderDate)/7*7,-1) AS DATE)
        ,OrderValue     = SUM(od.MOrderQty * od.MPrice)
   INTO #PreAgg
   FROM dbo.OrdMaster om
   JOIN dbo.OrdDetail od ON om.SalesOrder = od.SalesOrder 
  WHERE om.OrderDate    >= DATEADD(WK,-17,DATEADD(dd,DATEDIFF(dd,-1,GETDATE())/7*7,-1))
    AND om.OrderDate    <  DATEADD(dd,DATEDIFF(dd,-1,GETDATE())/7*7,-1)
  GROUP BY DATEDIFF(dd,-1,om.OrderDate)/7*7
;
--===== Declare a place to build the dynamic SQL in.
DECLARE @SQL VARCHAR(8000)
;
--===== Create the dynamic SELECT list of the CROSSTAB from the preggregated table.
 SELECT @SQL  = ISNULL(@SQL+SPACE(8)+',','')
              + REPLACE(REPLACE(
                    '[<<WeekDate>>] = SUM(CASE WHEN WeekDate = "<<WeekDate>>" THEN OrderValue ELSE 0 END)
'               ,'"'           ,'''') --These are the other end of the replaces.
                ,'<<WeekDate>>',CONVERT(CHAR(8),WeekDate,1))
   FROM #PreAgg
  ORDER BY WeekDate
;
--===== Create the static parts of the dynamic CROSSTAB SQL and insert the dynamic part.
 SELECT @SQL = REPLACE('
 SELECT  <<@SQL>>        ,[Total]    = SUM(OrderValue)
   FROM #Preagg
;'      ,'<<@SQL>>',@SQL) --The other end of the replace
;
--===== Display the dynamic SQL for troubleshooting purposes.
     -- This can be commented out for production.
  PRINT @SQL
;
--===== Execute the dynamic SQL
   EXEC (@SQL)
;

尝试:

Select datepart(week, om.OrderDate)),
SUM(MOrderQty * MPrice) as OrderValue 
from OrdMaster om 
inner join OrdDetail od 
        on om.SalesOrder = od.SalesOrder 
where om.OrderDate >= DATEADD(WEEK, -17,getdate()) 
group by datepart(week, om.OrderDate))

这里

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM