Stocktaking Table
StoreID Date ProductCode Qty
1 2016-07-30 11 58
1 2016-09-30 11 97
2 2016-08-30 12 15
2 2016-09-22 55 10
3 2016-09-05 55 10
Sale Table
StoreID Date ProductCode Qty
1 2016-08-30 11 40
2 2016-08-30 12 3
2 2016-08-30 55 4
3 2016-08-30 55 6
Desired Output
StoreID Date Productcode Qty
1 2016-08-30 11 18
2 2016-08-30 12 12
2 2016-08-30 55 6
3 2016-08-30 55 4
参数
@ date1 and @date2 @storeid
我需要展示日常库存;我可以显示stocktakingQty -saleQty = Todayinventory
我喜欢这个
StoreID Date Productcode Qty
1 2016-08-30 11 18
2 2016-08-30 12 12
2 2016-08-30 55 -4
3 2016-08-30 55 -6
我无法在这里显示负值。
这里的问题是他们忘了在8th month
store ID 3,2
期间进行盘点,但他们在product Code 55
上卖出了2016-08-30
。下个月他们在product Code 55
期间的库存为9th month
。
我不知道该怎么办!! bcoz如果它唯一的负数值我需要选择下个月的股票拍卖日期,否则我选择了第8个股票拍摄日期。
也许有人可以帮忙!!
Declare
@date1 date = '2015-06-01'
,@date2 date = '2015-06-30'
,@StoreNo Nvarchar(Max)=' AND S.StoreNo IN (61,68,450,451,430,917,918,919,921,923,925,930,935)'
--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 S.StoreNo IN (61,68,450,451,430,917,918,919,921,923,925,930,935)' + @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
where STD.StoreNo IN (select StoreNo from ##StoreList )
group By STD.StoreNo,STD.ProductBarCode,CheckDate
SELECT A.StoreNo as StoreNo ,C.[date] as Date,A.ProductBarCode as ProductBarCode,A.ProductQty as ProductQty
INTO ##inv1
FROM #calender C
OUTER APPLY
(
SELECT TOP 100 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 S.StoreNo,s.Date,s.ProductBarCode,ISNULL (sum(s.ProductQty),0) as ProductQty
From
(Select StoreNo,Date,ProductBarCode,ProductQty from ##inv1 where Date between @date_s and @date_e and StoreNo IN (select StoreNo from ##StoreList )
Union all
--Buy
Select
BuyStore as StoreNo
,BuyDate as Date
,ProductBarCode as ProductBarCode
,SUM(BuyQty)as Qty
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
)S
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)*(-1) 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) 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)*(-1) 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)*(-1) 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
--RCVBackDetail
Select
RcvBackStoreNo as StoreNo
,ProductBarCode as ProductBarCode
,SUM(RcvBackQty) 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
BEGIN
Select
f.StoreNo,f.Date,f.ProductBarCode,SUM(f.ProductQty) as ProductQty
INTO ##Inv2
From
(Select StoreNo,Date,ProductBarCode,ProductQty From #inventory i
union all
Select StoreNo,Date,ProductBarCode,ProductQty From #Stock st)f
Group By f.Date,f.ProductBarCode,f.StoreNo
End
BEGIN
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
SELECT @cols = STUFF((SELECT distinct ',' + QUOTENAME([StoreNo])
FROM ##StoreList
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SELECT @query =
'SELECT * FROM
(SELECT
[StoreNo],
p.Date as Date
,p.ProductBarCode
,(ProductQty) as productQty
FROM ##inv2 f
Right Join ##product P ON p.ProductBarCode =f.ProductBarCode and p.Date =f.Date
where
p.ProductBarCode IN(2300028813032,2221400000393,2300011512096,2300021714060)
)X
PIVOT
(
SUM(ProductQty)
for [StoreNo] in (' + @cols + ')
) P'
EXEC SP_EXECUTESQL @query
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)
这个解决方案解决了什么是instock和订单在30/08,计算salesqty然后计算两个阶段的剩余库存。注意 - 输入数据与你的输入数据不完全相同 - 这样我就可以测试几种情况,
declare @st table(StoreID int , Dte date, ProductCode int, Qty int)
insert into @st values
( 1, '2016-07-30', 11, 58),
( 1, '2016-09-30', 11, 97),
( 2, '2016-08-30', 12, 15),
( 2, '2016-08-22', 55, 2),
( 2, '2016-09-22', 55, 10),
( 3, '2016-09-05', 55, 10)
declare @s table (StoreID int, Dte date, ProductCode int, Qty int)
insert into @s values
( 1, '2016-08-30', 11, 40),
( 2, '2016-08-30', 12, 15),
( 2, '2016-08-30', 55, 4),
( 3, '2016-08-30', 55, 6)
drop table #temp
;with cte as
(
select t.storeid,t.stockstatusdate,t.productcode,sum(t.instock) instock ,sum(t.onorder) onorder
from
(
select st.storeid
, year(st.dte) * 12 + month(st.dte) yyyymm
, 2016 * 12 + 8 as stockstatusdate
, st.productcode,
isnull(case when year(st.dte) * 12 + month(st.dte) <= 2016 * 12 + 8 then sum(st.qty) end ,0)as instock,
isnull(case when year(st.dte) * 12 + month(st.dte) > 2016 * 12 + 8 then sum(st.qty) end ,0) as onorder
from @st st
group by st.storeid
, year(st.dte) * 12 + month(st.dte)
,st.productcode
) t
group by t.storeid,t.stockstatusdate,t.productcode
)
select cte.storeid,cte.stockstatusdate,cte.productcode,cte.instock,cte.instock as instockcalc,cte.onorder, cte.onorder as onordercalc,
t.saleqty,t.saleqtycalc
into #temp
from cte
join
(select s.storeid,year(s.dte) * 12 + month(s.dte) as salesdate,s.productcode ,sum(s.qty) as saleqty, sum(s.qty) as saleqtycalc
from @s s
group by s.storeid,year(s.dte) * 12 + month(s.dte),s.productcode
) t on t.storeid = cte.storeid and t.salesdate = cte.stockstatusdate and t.productcode = cte.productcode
--select * from #temp
update #temp
set instockcalc =
case
when instockcalc >= saleqtycalc then instockcalc - saleqtycalc
else 0
end,
saleqtycalc =
case
when instockcalc >= saleqtycalc then 0
else saleqtycalc - instockcalc
end
where saleqtycalc > 0
update #temp
set onordercalc =
case
when onordercalc >= saleqtycalc then onordercalc - saleqtycalc
else 0
end,
saleqtycalc =
case
when onordercalc >= saleqtycalc then 0
else saleqtycalc - onordercalc
end
where saleqtycalc > 0
--select * from #temp
select storeid,stockstatusdate,productcode,
case
when instockcalc <> 0 then instockcalc
else onordercalc
end as qty
from #temp
答案 1 :(得分:0)
不确定以下查询是否能完全解决您的问题,但是case和datepart函数应该会有所帮助。
假设我们可以将上个月30日到本月30日之间的库存量视为上个月的30日,那么下面的查询将会得到预期的结果
例如:如果在该商店的特定产品在9月22日或5日完成库存,那么我们可以假设它应该在8月30日实际发生。
SELECT st.StoreID,
CASE
WHEN st.date < (CAST(CAST(DATEPART(yyyy,st.date) AS VARCHAR(5)) + '-' + CAST(DATEPART(mm, st.date) AS VARCHAR(5)) + '-30' AS DATE)) THEN
CAST(CAST(DATEPART(yyyy,st.date) AS VARCHAR(5)) + '-' + CAST((DATEPART(mm, st.date)-1) AS VARCHAR(5)) + '-30' AS DATE)
WHEN st.date = (CAST(CAST(DATEPART(yyyy,st.date) AS VARCHAR(5)) + '-' + CAST(DATEPART(mm, st.date) AS VARCHAR(5)) + '-30' AS DATE)) THEN st.date END AS [stockdate],
st.ProductCode,
s.date AS salesDate,
st.Qty - s.Qty AS InventoryQuantity
FROM dbo.stocktaking st
LEFT JOIN dbo.SALE s
ON st.StoreID =s.StoreID
AND st.ProductCode = s.ProductCode
WHERE CASE
WHEN st.date < (CAST(CAST(DATEPART(yyyy,st.date) AS VARCHAR(5)) + '-' + CAST(DATEPART(mm, st.date) AS VARCHAR(5)) + '-30' AS DATE)) THEN
CAST(CAST(DATEPART(yyyy,st.date) AS VARCHAR(5)) + '-' + CAST((DATEPART(mm, st.date)-1) AS VARCHAR(5)) + '-30' AS DATE)
WHEN st.date = (CAST(CAST(DATEPART(yyyy,st.date) AS VARCHAR(5)) + '-' + CAST(DATEPART(mm, st.date) AS VARCHAR(5)) + '-30' AS DATE)) THEN st.date END <= s.date
答案 2 :(得分:0)
SELECT A.StoreNo as StoreNo ,C.[date] as Date,A.ProductBarCode as ProductBarCode,A.ProductQty as ProductQty
INTO ##inv1
FROM #calender C
OUTER APPLY
(
SELECT DISTINCT TOP 100 percent * FROM ##Temp I WHERE I.Date <= C.DATE and StoreNo IN (select StoreNo from ##StoreList ) ORDER BY I.Date
) A
--where A.productBarcode =2300007115072
OPTION (maxrecursion 0)
SELECT B.StoreNo as StoreNo ,C.[date] as Date,B.ProductBarCode as ProductBarCode,B.ProductQty as ProductQty
INTO ##inv2
FROM #calender C
OUTER APPLY
(
SELECT DISTINCT TOP 100 percent * FROM ##Temp I WHERE I.Date >= C.DATE and StoreNo IN (select StoreNo from ##StoreList ) ORDER BY I.Date
) B
--where A.productBarcode =2300007115072
OPTION (maxrecursion 0)
BEGIN
Select
i.StoreNo
,i.Date
,i.ProductBarCode
,ISNULL(i.ProductQty - (Select SUM(Productqty) from #Stock st where st.Date<=i.Date and i.StoreNo =st.StoreNo and i.ProductBarCode= st.ProductBarCode),i.ProductQty ) as ProductQty
INTO ##final1
From #inv1 i
left join #Stock s
on s.storeno=i.storeno
and s.productbarcode=i.productbarcode
and s.date=i.date
--where i.ProductBarCode IN(2221400000393)
Order By StoreNo,Date ,productBarcode
Select
i.StoreNo
,i.Date
,i.ProductBarCode
,ISNULL(i.Qty - (Select SUM(Productqty) from #Stock st where st.Date<=i.Date and i.StoreNo =st.StoreNo and i.ProductBarCode= st.ProductBarCode),i.Qty ) as ProductQty
INTO ##final2
From #inv2 i
left join #Stock s
on s.storeno=i.storeno
and s.productbarcode=i.productbarcode
and s.date=i.date
--where i.ProductBarCode IN(2221400000393)
Order By StoreNo,Date ,productBarcode
END
BEGIN
Select f1.StoreNo as StoreNo,f1.Date as Date,f1.ProductBarCode as ProductBarCode,
case when f1.ProductQty <0 then f2.ProductQty else f1.ProductQty end as ProductQty
INTO ##final3
From ##final1 f1
Full Outer Join ##final2 f2
ON f2.Date = f1.Date and f2.ProductBarCode = f1.ProductBarCode and f1.StoreNo = f2.StoreNo
order By Date