简体   繁体   English

更新表变量而不复制 T-SQL 中的数据

[英]Update a table variable without duplicating data in T-SQL

I have 2 table variables @Items and @Locations .我有 2 个表变量@Items@Locations Both tables contain a volume column for items and locations.两个表都包含一个用于项目和位置的数量列。

I am trying to retrieve locations with the available volume capacity per item.我正在尝试使用每个项目的可用卷容量来检索位置。 I would like the location to be excluded from the results if it has no more volume capacity to hold any other item.如果该位置没有更多容量来容纳任何其他项目,我希望从结果中排除该位置。 The goal is to update @Items with available locations based on the volume and ignore the location if it can't store any more items.目标是根据体积使用可用位置更新@Items ,如果无法存储更多项目,则忽略该位置。

Here is the T-SQL that I have written for this scenario:这是我为此场景编写的 T-SQL:

DECLARE @Items TABLE
(
    Id INT,
    Reference NVARCHAR(255),
    Volume DECIMAL(18, 4),
    IdLocation INT
)

DECLARE @Locations TABLE
(
    Id INT,
    Reference NVARCHAR(255),
    Volume DECIMAL(18, 4)
)

INSERT INTO @Locations (Id, Reference, Volume)
    SELECT 100, 'Location 1', 50000
    UNION SELECT 101, 'Location 2', 100000
    UNION SELECT 102, 'Location 3', 300000

INSERT INTO @Items (Id, Reference, Volume)
    SELECT 1, 'Item 1', 50000
    UNION SELECT 2, 'Item 2', 50000
    UNION SELECT 3, 'Item 3', 100000
    UNION SELECT 4, 'Item 4', 100000
    UNION SELECT 5, 'Item 5', 300000
    UNION SELECT 6, 'Item 6', 300000
    UNION SELECT 7, 'Item 7', 300000

UPDATE I
SET I.IdLocation = (SELECT TOP 1 L.Id 
                    FROM @Locations L
                    WHERE L.Volume >= I.Volume)
FROM @Items I

SELECT *
FROM @Items

The results which I get:我得到的结果:

非预期结果

The results which I expect to get:我期望得到的结果:

预期成绩

If anyone has a solution to this problem I would be very grateful.如果有人能解决这个问题,我将不胜感激。

There is probably a clever set-based way to do this involving window functions and a running total of allocated volume.可能有一种聪明的基于集合的方法来做到这一点,涉及窗口函数和分配的卷的运行总量。 Personally when having to allocate stock like this I often find myself resorting to a loop eg就个人而言,当不得不像这样分配库存时,我经常发现自己求助于循环,例如

declare @Count int;

-- How many items are there to update?
select @Count = count(*) from @Items where IdLocation is null

while exists (select 1 from @Items where IdLocation is null) begin
  UPDATE I SET
    I.IdLocation = (
      SELECT TOP 1 L.Id 
      FROM @Locations L
      WHERE (L.Volume - coalesce((select sum(I1.Volume) from @Items I1 where I1.IdLocation = L.id),0)) >= I.Volume
    )
  FROM @Items I
  where I.id in (select top 1 id from @Items where IdLocation is null);

  -- Did we update any items? If not exit the loop as we have allocated all space.
  if @Count = (select count(*) from @Items where IdLocation is null) break;

  -- If so, update the new count for the next loop
  select @Count = count(*) from @Items where IdLocation is null;
end

SELECT *
FROM @Items;

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

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