CTE 不更新所有选定的行
CTE not updating all the selected rows
我正在尝试对库存实施 FIFO。
我有以下 table 与库存相关:
Lot:
ID,SiteID,WHID,BatchID,Qty,Amount,QtyRemaning,AmountRemaning,LastQtyOut,DimComb, . . .
Dispatch Note:
ID,ProductID,SiteID,WHID,Quantity,DimComb, . . .
我有一个查询,它计算累积总和并根据 FIFO 出库:
;WITH CTE AS (
SELECT
DN.fldQty as DNQty,
DN.fldProductID as DNProductID,
lot.fldProductID as LotsProductID,
lot.fldID as LotID,
lot.fldQtyRemaning as QtyRemaning,
lot.fldUnitCost as UnitCost,
lot.fldQty as LotQty,
lot.fldAmountRemaning as AmountRemaning,
lot.fldLastQtyOut as LastQtyOut,
lot.fldLastUpdateRefDoc as fldLastUpdateRefDoc,
lot.fldLastUpdateRefDocNum as fldLastUpdateRefDocNum,
DN.DimComb as DNDimComb,
lot.DimComb,
CumulativeSum= SUM(lot.fldQtyRemaning)
OVER
(PARTITION BY
DN.DimComb,
lot.fldProductID,
lot.fldSiteID,
lot.fldWHID,
lot.fldLocationID,
lot.fldPalletID--,
--lot.fldBatchID
ORDER BY lot.fldID ROWS UNBOUNDED PRECEDING)
FROM
#tmpTblDN DN
RIGHT JOIN
lot lot
ON
--lot.fldRefDocNum = tblGRNItems.fldGRNID AND
ISNULL(DN.fldProductID,0) = ISNULL(lot.fldProductID,0) AND
ISNULL(DN.fldSiteID,0) = ISNULL(lot.fldSiteID,0) AND
ISNULL(DN.fldWHID,0) = ISNULL(lot.fldWHID,0) AND
ISNULL(DN.fldLocationID,0) = ISNULL(lot.fldLocationID,0) AND
ISNULL(DN.fldPalletID,0) = ISNULL(lot.fldPalletID,0) --AND
--ISNULL(tblSIRItems.fldBatchID,0) = ISNULL(lot.fldBatchID,0)
WHERE
DN.fldDNID = @DNID
AND lot.fldQtyRemaning > 0
)
UPDATE
CTE
SET
QtyRemaning = CASE
WHEN (CumulativeSum - DNQty) < 0 AND DNProductID = LotsProductID THEN 0
WHEN (CumulativeSum - DNQty) BETWEEN 0 AND QtyRemaning AND DNProductID = LotsProductID THEN (CumulativeSum - DNQty)
ELSE QtyRemaning
END ,
LastQtyOut = CASE
WHEN (CumulativeSum - DNQty) < 0 AND DNProductID = LotsProductID THEN QtyRemaning
WHEN (CumulativeSum - DNQty) BETWEEN 0 AND QtyRemaning AND DNProductID = LotsProductID THEN
CASE WHEN LotQty = QtyRemaning THEN
(QtyRemaning - (CumulativeSum - DNQty))
ELSE
(CumulativeSum - (CumulativeSum - DNQty))
END
ELSE LastQtyOut
END ,
AmountRemaning = CASE
WHEN (CumulativeSum - DNQty) < 0 AND DNProductID = LotsProductID THEN AmountRemaning - (QtyRemaning * UnitCost)
WHEN (CumulativeSum - DNQty) BETWEEN 0 AND QtyRemaning AND DNProductID = LotsProductID THEN
CASE WHEN LotQty = QtyRemaning THEN
AmountRemaning - ((QtyRemaning - (CumulativeSum - DNQty)) * UnitCost)
ELSE
AmountRemaning - ((CumulativeSum - (CumulativeSum - DNQty)) * UnitCost)
END
ELSE AmountRemaning
END ,
fldDimComb = DNDimComb,
fldLastUpdateRefDoc = 'DispatchNote',
fldLastUpdateRefDocNum = @DNID
FROM CTE
WHERE CumulativeSum <= QtyRemaning + DNQty
现在我有相同的 ProductID,但 DN 中有不同的 Quantity 和不同的 DimComb,CTE 在 select 上显示以下结果:
DNQty | DNProductID | LotsProductID | LotID | QtyRemaning | UnitCost | LotQty | AmountRemaning | LastQtyOut | CumulativeSum |
2 | 14 | 14 | 783 | 100 | 3 | 100 | 300 | NULL | 100 |
3 | 14 | 14 | 783 | 100 | 3 | 100 | 300 | NULL | 100 |
但问题是,它只更新 Lot table 第一行的 DNQty 2。
我也评论了 WHERE 子句,但它也不起作用。
我认为它不会用第二行(即 DNQty 3 的行)更新 Lot table,因为这两行都引用 Lot table 中的同一行(即 LotID 783)。
如有任何帮助,我们将不胜感激。
I think its not updating the Lot table with 2nd row (.i.e. the row
with DNQty 3) because the both rows refer to same row in Lot table
(.i.e LotID 783).
是的,正是这样。
您的示例可以简化为:
create table #tmpTblDN (DNQty int, DNProductID int);
insert into #tmpTblDN values (2, 14), (3, 14);
create table #lot (LotsProductID int,
LotID int,
QtyRemaning int,
UnitCost int,
LotQty int,
AmountRemaning int,
LastQtyOut int,
CumulativeSum int);
insert into #lot values
(14, 783, 100, 3, 100, 300, NULL, 100)
;WITH CTE AS
(
SELECT *
FROM
#tmpTblDN DN
RIGHT JOIN
#lot lot
on dn.DNProductID = lot.LotsProductID
)
UPDATE
CTE
SET
--select *,
QtyRemaning = CASE
WHEN (CumulativeSum - DNQty) < 0 AND DNProductID = LotsProductID THEN 0
WHEN (CumulativeSum - DNQty) BETWEEN 0 AND QtyRemaning AND DNProductID = LotsProductID THEN (CumulativeSum - DNQty)
ELSE QtyRemaning
END
FROM CTE
WHERE CumulativeSum <= QtyRemaning + DNQty
所以你清楚地看到你的第一个 table 包含 2 行,但是你对第二个 table (通过 cte)做了一个 update
只有一行。
可以在 "Updating Data Based on Data From Other Tables":
部分下的 BOL 文章 UPDATE (Transact-SQL) 中找到对此的解释
In this case I want to update Lot with ID 783 by subtracting DNQty 2
and 3 (i.e. In first update LotQtyRemaning should have value of 98,
and after second update it should have value of 95).
这意味着你想 update
你的 Lot
table 通过使用 DNQty 的 sum
,所以首先你应该编写一个聚合查询来计算 sum(DNQty)
,这样你保证每个 LotsProductID
将只有一个对应的 DNProductID
(在我的例子中。在你的例子中你应该 group by
你在你的 join
然后使用所有字段 join
将您的聚合结果 Lot
table)
update lot
set QtyRemaning = CASE
WHEN (CumulativeSum - DNQty) < 0 AND DNProductID = LotsProductID THEN 0
WHEN (CumulativeSum - DNQty) BETWEEN 0 AND QtyRemaning AND DNProductID = LotsProductID THEN (CumulativeSum - DNQty)
ELSE QtyRemaning
END
from #lot lot
join (select DNProductID, sum(DNQty) as DNQty
from #tmpTblDN
group by DNProductID) dn
on dn.DNProductID = lot.LotsProductID
我正在尝试对库存实施 FIFO。
我有以下 table 与库存相关:
Lot:
ID,SiteID,WHID,BatchID,Qty,Amount,QtyRemaning,AmountRemaning,LastQtyOut,DimComb, . . .
Dispatch Note:
ID,ProductID,SiteID,WHID,Quantity,DimComb, . . .
我有一个查询,它计算累积总和并根据 FIFO 出库:
;WITH CTE AS (
SELECT
DN.fldQty as DNQty,
DN.fldProductID as DNProductID,
lot.fldProductID as LotsProductID,
lot.fldID as LotID,
lot.fldQtyRemaning as QtyRemaning,
lot.fldUnitCost as UnitCost,
lot.fldQty as LotQty,
lot.fldAmountRemaning as AmountRemaning,
lot.fldLastQtyOut as LastQtyOut,
lot.fldLastUpdateRefDoc as fldLastUpdateRefDoc,
lot.fldLastUpdateRefDocNum as fldLastUpdateRefDocNum,
DN.DimComb as DNDimComb,
lot.DimComb,
CumulativeSum= SUM(lot.fldQtyRemaning)
OVER
(PARTITION BY
DN.DimComb,
lot.fldProductID,
lot.fldSiteID,
lot.fldWHID,
lot.fldLocationID,
lot.fldPalletID--,
--lot.fldBatchID
ORDER BY lot.fldID ROWS UNBOUNDED PRECEDING)
FROM
#tmpTblDN DN
RIGHT JOIN
lot lot
ON
--lot.fldRefDocNum = tblGRNItems.fldGRNID AND
ISNULL(DN.fldProductID,0) = ISNULL(lot.fldProductID,0) AND
ISNULL(DN.fldSiteID,0) = ISNULL(lot.fldSiteID,0) AND
ISNULL(DN.fldWHID,0) = ISNULL(lot.fldWHID,0) AND
ISNULL(DN.fldLocationID,0) = ISNULL(lot.fldLocationID,0) AND
ISNULL(DN.fldPalletID,0) = ISNULL(lot.fldPalletID,0) --AND
--ISNULL(tblSIRItems.fldBatchID,0) = ISNULL(lot.fldBatchID,0)
WHERE
DN.fldDNID = @DNID
AND lot.fldQtyRemaning > 0
)
UPDATE
CTE
SET
QtyRemaning = CASE
WHEN (CumulativeSum - DNQty) < 0 AND DNProductID = LotsProductID THEN 0
WHEN (CumulativeSum - DNQty) BETWEEN 0 AND QtyRemaning AND DNProductID = LotsProductID THEN (CumulativeSum - DNQty)
ELSE QtyRemaning
END ,
LastQtyOut = CASE
WHEN (CumulativeSum - DNQty) < 0 AND DNProductID = LotsProductID THEN QtyRemaning
WHEN (CumulativeSum - DNQty) BETWEEN 0 AND QtyRemaning AND DNProductID = LotsProductID THEN
CASE WHEN LotQty = QtyRemaning THEN
(QtyRemaning - (CumulativeSum - DNQty))
ELSE
(CumulativeSum - (CumulativeSum - DNQty))
END
ELSE LastQtyOut
END ,
AmountRemaning = CASE
WHEN (CumulativeSum - DNQty) < 0 AND DNProductID = LotsProductID THEN AmountRemaning - (QtyRemaning * UnitCost)
WHEN (CumulativeSum - DNQty) BETWEEN 0 AND QtyRemaning AND DNProductID = LotsProductID THEN
CASE WHEN LotQty = QtyRemaning THEN
AmountRemaning - ((QtyRemaning - (CumulativeSum - DNQty)) * UnitCost)
ELSE
AmountRemaning - ((CumulativeSum - (CumulativeSum - DNQty)) * UnitCost)
END
ELSE AmountRemaning
END ,
fldDimComb = DNDimComb,
fldLastUpdateRefDoc = 'DispatchNote',
fldLastUpdateRefDocNum = @DNID
FROM CTE
WHERE CumulativeSum <= QtyRemaning + DNQty
现在我有相同的 ProductID,但 DN 中有不同的 Quantity 和不同的 DimComb,CTE 在 select 上显示以下结果:
DNQty | DNProductID | LotsProductID | LotID | QtyRemaning | UnitCost | LotQty | AmountRemaning | LastQtyOut | CumulativeSum |
2 | 14 | 14 | 783 | 100 | 3 | 100 | 300 | NULL | 100 |
3 | 14 | 14 | 783 | 100 | 3 | 100 | 300 | NULL | 100 |
但问题是,它只更新 Lot table 第一行的 DNQty 2。
我也评论了 WHERE 子句,但它也不起作用。 我认为它不会用第二行(即 DNQty 3 的行)更新 Lot table,因为这两行都引用 Lot table 中的同一行(即 LotID 783)。
如有任何帮助,我们将不胜感激。
I think its not updating the Lot table with 2nd row (.i.e. the row with DNQty 3) because the both rows refer to same row in Lot table (.i.e LotID 783).
是的,正是这样。
您的示例可以简化为:
create table #tmpTblDN (DNQty int, DNProductID int);
insert into #tmpTblDN values (2, 14), (3, 14);
create table #lot (LotsProductID int,
LotID int,
QtyRemaning int,
UnitCost int,
LotQty int,
AmountRemaning int,
LastQtyOut int,
CumulativeSum int);
insert into #lot values
(14, 783, 100, 3, 100, 300, NULL, 100)
;WITH CTE AS
(
SELECT *
FROM
#tmpTblDN DN
RIGHT JOIN
#lot lot
on dn.DNProductID = lot.LotsProductID
)
UPDATE
CTE
SET
--select *,
QtyRemaning = CASE
WHEN (CumulativeSum - DNQty) < 0 AND DNProductID = LotsProductID THEN 0
WHEN (CumulativeSum - DNQty) BETWEEN 0 AND QtyRemaning AND DNProductID = LotsProductID THEN (CumulativeSum - DNQty)
ELSE QtyRemaning
END
FROM CTE
WHERE CumulativeSum <= QtyRemaning + DNQty
所以你清楚地看到你的第一个 table 包含 2 行,但是你对第二个 table (通过 cte)做了一个 update
只有一行。
可以在 "Updating Data Based on Data From Other Tables":
部分下的 BOL 文章 UPDATE (Transact-SQL) 中找到对此的解释In this case I want to update Lot with ID 783 by subtracting DNQty 2 and 3 (i.e. In first update LotQtyRemaning should have value of 98, and after second update it should have value of 95).
这意味着你想 update
你的 Lot
table 通过使用 DNQty 的 sum
,所以首先你应该编写一个聚合查询来计算 sum(DNQty)
,这样你保证每个 LotsProductID
将只有一个对应的 DNProductID
(在我的例子中。在你的例子中你应该 group by
你在你的 join
然后使用所有字段 join
将您的聚合结果 Lot
table)
update lot
set QtyRemaning = CASE
WHEN (CumulativeSum - DNQty) < 0 AND DNProductID = LotsProductID THEN 0
WHEN (CumulativeSum - DNQty) BETWEEN 0 AND QtyRemaning AND DNProductID = LotsProductID THEN (CumulativeSum - DNQty)
ELSE QtyRemaning
END
from #lot lot
join (select DNProductID, sum(DNQty) as DNQty
from #tmpTblDN
group by DNProductID) dn
on dn.DNProductID = lot.LotsProductID