使用其他 table 的前 1 个字段更新 table

Update table with top 1 field from other table

我已经为此奋斗了几天。我有一个基于条形码字段的库存 table。我还有一个包含多个条目的位置 table,因为此项目可能已移动多次。我想在库存 table 中添加一个 current_location 字段,显示物品最后移动到的位置。因此,我希望位置 table 中的 location_to 字段具有最新的 date_modified。我不太明白这个问题。

所以库存 table 有(每个条形码只有一个条目):

barcode=xxx current_location = null
barcode=yyy current_location = null

位置 table 有(每个条形码多个条目):

barcode = xxx, location_to = 1, datemodified = 01/01/2022
barcode = xxx, location_to = 2, datemodified = 01/02/2022
barcode = xxx, location_to = 3, datemodified = 01/03/2022
barcode = yyy, location_to = 4, datemodified = 01/04/2022
barcode = yyy, location_to = 5, datemodified = 01/05/2022
barcode = yyy, location_to = 6, datemodified = 01/06/2022

我想为 xxx 设置 inventory.current_location = 3,为 yyy 设置 6,因为它们是最新的,通过 datemodified。

我试过这样的事情:

update Inventory
set current_location = 
L.location_to 
from Inventory I
inner join Location L on I.Barcode = L.Barcode
where L.DateModified = (select top 1 L.DateModified where I.Barcode = L.Barcode order by L.DateModified DESC)

但是这个 returns xxx 和 yyy 相同 current_location 作为顶部的一个没有指定每个条形码。

我希望这是有道理的,因为我的大脑被炸了,我无法完全理解它。我希望问题的初步描述足够了,因为我认为我正在尝试的代码是错误的,只是混淆了整个问题。

感谢您阅读本文。我知道你们中的一些人会认为这是一个简单的问题,一旦我看到解决方案,我可能也会。

Straightforward 是带有子选择的子选择,适用于每个 DBMS:

UPDATE Inventory i SET current_location = (
      SELECT l1.location_to from Location l1
       WHERE l1.barcode = i.barcode and 
             l1.datemodified = (SELECT max(l2.datemodified) from Location l2
                                 WHERE l2.barcode = i.barcode))

DB Fiddle

您的查询存在一些问题,尤其是您的子查询丢失 from location。从您对 top 1 的使用来看,您可能正在使用 SQL 服务器。

您可以使用 CTE 执行更新,例如:

with i as (
    select i.current_location, l.Location_to
    from Inventory i
    cross apply (
        select top (1) l.Location_to
        from location l
        where l.Barcode = i.Barcode 
        order by l.DateModified desc
    )l
)
update i set current_location = Location_to;

假设您正在使用 SQL 服务器,因为您已经将 TOP 1 放在那里,那么这应该可以工作:

UPDATE Inventory
SET current_location = L.location_to 
FROM Inventory I
INNER JOIN (
            SELECT Barcode, location_to, ROW_NUMBER() OVER (PARTITION BY Barcode ORDER BY DateModified DESC) AS rownum 
            FROM [Location]
            ) L on I.Barcode = L.Barcode
WHERE L.rownum = 1;

我更喜欢 Stu 的查询,但如果您想“修复”您的查询,这应该可行。

注意在 DateModified 子查询中将 location 添加为 L2

update Inventory
set current_location = 
L.location_to 
from Inventory I
inner join Location L on I.Barcode = L.Barcode
where L.DateModified = (select top 1 L2.DateModified from [location] L2 where I.Barcode = L.Barcode order by L2.DateModified DESC)