以下查询我已经为每个商店的每日库存销售写了一个月的2百万行数据,就像我有超过250店! 它花费的时间比预期的要长!!
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<=@date2
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 >=@date_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 '+''''+' '+''''+','+@pheader
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
我有点想法为什么它的速度很慢,如果添加产品表需要很长时间!!但我不知道如何更改和编写查询! 如何写另一种方法来减少运行时间和在数据透视表期间我只能添加一个商店号但我想添加更多我不知道为什么它没有得到多个参数输入!
如果有人可以建议或帮助! 预先感谢您的帮助
答案 0 :(得分:0)
为所有大型临时表创建索引。刚刚通过(SELECT INTO)填充它们