2016-08-24 10 views
-2

以下のクエリでは、各店舗の毎日の在庫管理用に2millonの行データを持っていると書いています。 それ以上の時間がかかることが予想されます!SQLサーバーで複数の入力パラメータをピボットする方法クエリの実行時間を短縮する方法

ALTER PROCEDURE [dbo].[getDaily] 

--Declare 
      @date1 date = '2015-06-01' 
       ,@date2 date = '2015-06-30' 
       ,@StoreNo Nvarchar(Max)=' AND S.StoreNo IN (61,63,450,451)' 


AS 
BEGIN 
      IF Object_ID(N'tempdb..#calender') IS NOT NULL DROP TABLE #calender 
       IF Object_ID(N'tempdb..##Temp') IS NOT NULL DROP TABLE ##Temp 
       IF Object_ID(N'tempdb..##Inv1') IS NOT NULL DROP TABLE ##Inv1 
       IF Object_ID(N'tempdb..##Inv2') IS NOT NULL DROP TABLE ##Inv2 
        IF Object_ID(N'tempdb..#Stock') IS NOT NULL DROP TABLE #Stock 
        IF Object_ID(N'tempdb..##StoreList') IS NOT NULL DROP TABLE ##StoreList 
        IF Object_ID(N'tempdb..##final') IS NOT NULL DROP TABLE ##final 
        IF Object_ID(N'tempdb..##product') IS NOT NULL DROP TABLE ##product 

    Declare @sql_store nvarchar(max) 
      SET @sql_store = 
          'SELECT StoreNo,StoreName INTO ##StoreList FROM Store S WHERE StoreNo IN (61,63,450,451)' + @StoreNo 
      EXECUTE sp_executesql @sql_store 


      Declare 

       @date_s char(10) = cast(@date1 as varchar) 
       ,@date_e char(10) = cast(@date2 as varchar) 
       ,@date_index date 


        create Table #calender (Date date) 
        SET @date_index = @date1 

        WHILE @date_index<[email protected] 
        BEGIN 
        INSERT INTO #calender 
        SELECT @date_index 

        SET @date_index = dateadd(day,1,@date_index) 

        IF @date_index>@date2 
        Break 
        ELSE 
        Continue 
        END 


     BEGIN 
       SELECT 
          ProductNo as ProductBarCode,Date 

         INTO ##product 
            FROM Product,#calender 

        WHERE StartUseDate <= @date_s AND EndUseDate >[email protected]_e and IsInUsed = 1 

     END 

create table #inventory (StoreNo int ,Date date, ProductBarCode varchar(14),ProductQty int) 



     BEGIn 

        Select 
             STD.StoreNo As StoreNo 
             ,CheckDate as Date 
             ,ProductBarCode as ProductBarCode 
             , SUM(StocktakingQty)AS ProductQty 
          INTO ##Temp 
            From StockTakingDetail STD 
       Inner Join 
          (Select  
             StoreNo 
             ,CheckNo 
             ,CheckDate 
            From StockTakingMain SM)StocktakingMain 
           On STD.CheckNo =StockTakingMain.CheckNo 

          group By STD.StoreNo,STD.ProductBarCode,CheckDate 






        --Insert INTO #inventory  
           SELECT A.StoreNo ,C.[date],A.ProductBarCode,A.ProductQty 

          INTO ##inv1 
           FROM #calender C 
           OUTER APPLY 
           (
            SELECT TOP 50 PERCENT * FROM ##Temp I WHERE I.Date < C.DATE and StoreNo IN (select StoreNo from ##StoreList) ORDER BY I.Date 
           ) A 
           OPTION (maxrecursion 0) 


        --Insert INTO #inventory  
           SELECT B.StoreNo ,C.[date],B.ProductBarCode,B.ProductQty 

          INTO ##inv2 
           FROM #calender C 
           OUTER APPLY 
           (
            SELECT TOP 50 PERCENT * FROM ##temp I WHERE I.Date > C.DATE and StoreNo IN (select StoreNo from ##StoreList) ORDER BY I.Date 
           ) B 
           OPTION (maxrecursion 0) 


       INSERT INTO #inventory 
         Select S.StoreNo,s.Date,s.ProductBarCode,ISNULL (sum(s.ProductQty),0) as ProductQty 

         From 
         (Select StoreNo,Date,ProductBarCode,ProductQty from ##inv1 

         Union all 
         Select StoreNo,Date,ProductBarCode,ProductQty from ##inv2 
         )S 
         WHERE StoreNo IS NOT NULL 
         GROUP BY s.StoreNo,s.Date,s.ProductBarCode 

      END 



     BEGIN 

      select 
       S.Date as Date,S.StoreNo As StoreNo,(S.ProductBarCode) as ProductBarCode,sum(S.Qty) as ProductQty 
     INTO #Stock 
      from 
       --- sale 
       (
        select 
           StoreNo As StoreNo, 
           PluCode as ProductBarCode, 
           cast (sum(BuyPoint/100)as int) as Qty, 
           Date as Date 
        from POS_ItemTran p 
        where 
          Date between @date_s and @date_e and p.StoreNo IN(select StoreNo from ##StoreList) 
        Group by 
          PluCode,StoreNo,Date 

       union all 

       --Transfer IN 
         select 
           TD.TargetStoreNo as StoreNo 
           ,TD.ProductBarCode as ProductBarCode 
           ,SUM(TD.AcceptQty)*(-1) as Qty 
           ,AcceptDate as Date 
              from TransferDetail TD 
       Inner join 
          (Select TransferSerialNo 
          ,AcceptDate 
            from TransferMain)TM 

         ON TM.TransferserialNo = TD.TransferserialNo 
          where 
            AcceptDate between @date_s and @date_e and TargetStoreNo IN (select StoreNo from ##StoreList) 
           Group by 
            TargetStoreNo,TD.ProductBarcode,AcceptDate 

       union all 

       -- Transfer out 
          Select 
           TD.TransferStoreNo as StoreNo 
           , TD.ProductBarCode as ProductBarCode 
           ,SUM(TD.TransferQty) As Qty 
           ,TransferDate as Date 
              from TransferDetail TD 
       Inner Join 
          (Select TransferSerialNo 
             ,TransferDate 
              from TransferMain)TMO 
           On TMO.TransferSerialNo = TD.TransferSerialNo 
         where 
           TransferDate between @date_s and @date_e and TransferStoreNo IN (select StoreNo from ##StoreList) 
         Group by 
           TD.TransferStoreNo,TD.ProductBarCode,TransferDate 

       --Loss 
       UNION ALL 

        SELECT 
          StoreNo 
          ,LossProductBarCode 
          ,SUM(LossQty) as Qty, 
          LossDate as Date 

           FROM LossDetail LD 
       INNER JOIN 
        (SELECT 
         StoreNo 
         ,LossSerialNo 
         ,LossDate 
          FROM LossMain LM)LossMain ON LD.LossSerialNo = LossMain.LossSerialNo 
         where 
          LossDate between @date_s and @date_e and StoreNo IN (select StoreNo from ##StoreList) 
        GROUP BY 
          StoreNo,LossProductBarCode,LossDate 
       Union All 
        --Buy 
        Select 
          BuyStore as StoreNo 
          ,ProductBarCode as ProductBarCode 
          ,SUM(BuyQty)*(-1)as Qty 
           ,BuyDate as Date 
            from BuyDetail BD 
       Inner Join 
         (Select 
          BuySerialNo 
          ,BuyDate 
           from BuyMain BM) BuyMain ON BD.BuySerialNo = BuyMain.BuySerialNo 
        where 
          BuyDate Between @date_s and @date_e and BuyStore IN (select StoreNo from ##StoreList) 
        Group BY 
          BuyDate,BuyStore,ProductBarCode,BuyDate 

       Union All 
        --RCVBackDetail 
         Select 
          RcvBackStoreNo as StoreNo 
          ,ProductBarCode as ProductBarCode 
          ,SUM(RcvBackQty)*(-1) as Qty 
          ,RcvBackDate as Date 
         from RcvBackDetail RBD 
        Inner Join 
         (SELECT RcvBackSerialNo 
           ,RcvBackDate 
            FROM RcvBackMain)RcvBackMain 
         ON RcvBackMain.RcvBackSerialNo = RBD.RcvBackSerialNo 
         Where 
          RcvBackDate Between @date_s and @date_e and RcvBackStoreNo IN (select StoreNo from ##StoreList) 
         Group By 
           RcvBackDate,RcvBackStoreNo,ProductBarCode 


       )S 
         Group by S.StoreNo,S.ProductBarCode,S.Date 

       END 


    Declare  @pheader nvarchar(Max),@sql_pivot nvarchar(max) 

    Begin 

     SELECT @pheader=ISNULL(@pheader,'')+'['+StoreName+'],' 
                FROM ##StoreList GROUP BY StoreNo,StoreName ORDER BY StoreNo 
                SET @pheader= LEFT(@pheader, LEN(@pheader) - 1) 

                SET @sql_pivot= 
                 N'Select * from'+ 
                 '(
                  SELECT 

                    StoreName 
                    ,p.Date as Date 
                    ,p.ProductBarCode as ProductBarCode 
                    ,isnull(i.productqty-(select ProductQty as runningsum from #Stock st where st.date<=i.date and st.storeno=i.storeno and st.ProductBarCode = i.ProductBarCode),i.productqty) as ProductQty 

               From #inventory i 
                  LEFT JOIN Store S ON S.StoreNo = i.StoreNo 
                 Left JOIN #Stock st ON st.StoreNo = i.StoreNo and st.ProductBarCode = i.ProductBarCode and st.Date = i.Date 
                 left Join ##product p ON i.ProductBarCode = p.ProductBarCode and i.Date = P.Date 
                  --WHERE p.ProductBarCode IN (0065103700004, 
                   --        2017961746012) 
                  GROUP BY 

                    i.storeNo 
                    ,StoreName 
                    ,i.ProductBarCode 
                    ,p.ProductBarCode 
                    ,p.Date 
                    ,i.Date 
                    ,i.ProductQty)p 


                   pivot 
                   (sum(ProductQty) for [StoreName] IN ('+ @pheader+N') 
                   ) As Pivt order By Date,ProductBarCode' 


             EXECUTE sp_executesql @sql_pivot 


       SET @pheader = NULL 
       SELECT @pheader=ISNULL(@pheader,'')+'0 as ['+cast(StoreNo as varchar)+'],' 
       FROM ##StoreList GROUP BY StoreNo ORDER BY StoreNo 
       SET @pheader= LEFT(@pheader, LEN(@pheader) - 1) 

       SET @pheader = ' SELECT 0 as '+''''+'   '+''''+', 0 as '+''''+'   '+''''+','+'0 as '+''''+'   '+''''+', 0 as '+''''+'   '+''''+','[email protected] 
       EXECUTE sp_executesql @pheader 
    END 


Drop Table #inventory 
--Drop Table #calender 
IF Object_ID(N'tempdb..#inventory') IS NOT NULL DROP TABLE #inventory 
IF Object_ID(N'tempdb..#calender') IS NOT NULL DROP TABLE #calender 
IF Object_ID(N'tempdb..##Temp') IS NOT NULL DROP TABLE ##Temp 
IF Object_ID(N'tempdb..##Inv1') IS NOT NULL DROP TABLE ##Inv1 
       IF Object_ID(N'tempdb..##Inv2') IS NOT NULL DROP TABLE ##Inv2 
        IF Object_ID(N'tempdb..#Stock') IS NOT NULL DROP TABLE #Stock 
        IF Object_ID(N'tempdb..##StoreList') IS NOT NULL DROP TABLE ##StoreList 
        IF Object_ID(N'tempdb..##final') IS NOT NULL DROP TABLE ##final 
        IF Object_ID(N'tempdb..##product') IS NOT NULL DROP TABLE ##product 

END 

その、長い時間をかけて製品テーブルを追加する場合、私は、アイデアなぜその遅いのようなものを持っています!しかし、私はどのように変更し、クエリを書くか分からない! 実行時間を短縮し、ピボットテーブルの間に別の方法を書く方法私はストア番号を1つしか追加できませんが、私は何も追加したくありません。

誰かが提案したり手伝ったりできれば! 助けてくれてありがとう

答えて

0

すべての大きな一時テーブルのインデックスを作成します。経由して入力するとすぐに(SELECT INTO)

関連する問題