我正在尝试更新我的表格(LOCATIONS)以设置字段" NO_SHIP"到了' Y'满足以下条件时。请帮助,谢谢!
到目前为止,这是我的代码:
UPDATE LOCATIONS l
SET l.NO_SHIP='Y'
Where ARINVT.ID = FGMULTI.ARINVT_ID And FGMULTI.LOC_ID = L.ID
And ((FGMULTI.LOT_DATE + ARINVT.SHELF_LIFE) - SysDate) / ARINVT.SHELF_LIFE < .8
And L.LOC_DESC <> 'NC0101'
And ARINVT.CLASS = 'FG'
And L.ID <> 27051
答案 0 :(得分:0)
您无法加入update
本身,更不用说随意引入对其他表的引用。您需要使用相关子查询来标识要更新的行。类似的东西:
UPDATE LOCATIONS L
SET L.NO_SHIP = 'Y'
WHERE L.LOC_DESC <> 'NC0101'
AND L.ID <> 27051
AND (
SELECT MIN(((F.LOT_DATE + A.SHELF_LIFE) - SysDate) / A.SHELF_LIFE)
FROM FGMULTI F
JOIN ARINVT A ON A.ID = F.ARINVT_ID
WHERE F.LOC_ID = L.ID
AND A.CLASS = 'FG'
) < .8
相关性是子查询从外部更新语句引用L.ID
。
当然完全未经测试,因为我们没有您的表格定义或样本数据。希望这会指出你正确的方向。 (编辑在子查询中添加聚合函数,因此它只返回一行)。
或者您可以检查子查询中是否存在任何匹配的行:
UPDATE LOCATIONS L
SET L.NO_SHIP = 'Y'
WHERE L.LOC_DESC <> 'NC0101'
AND L.ID <> 27051
AND EXISTS (
SELECT null
FROM FGMULTI F
JOIN ARINVT A ON A.ID = F.ARINVT_ID
WHERE F.LOC_ID = L.ID
AND A.CLASS = 'FG'
AND ((F.LOT_DATE + A.SHELF_LIFE) - SysDate) / A.SHELF_LIFE < .8
);
你也可以让子查询包含自己的locations
副本,并加入另外两个表,找到相关的ID;然后让更新使用in
子句来更新与这些ID匹配的行。您可能想要检查每种方法的性能。
根据您的评论,您确实要更新fgmulti
,并且因为arinvt
和locations
之间没有明显的直接链接。如图所示,你可以使用这样的方法:
UPDATE FGMULTI
SET NO_SHIP = 'Y'
WHERE LOC_ID IN (
SELECT F.LOC_ID
FROM FGMULTI F
JOIN ARINVT A ON A.ID = F.ARINVT_ID
JOIN LOCATIONS L ON L.ID = F.LOC_ID
WHERE L.LOC_DESC <> 'NC0101'
AND L.ID <> 27051
AND A.CLASS = 'FG'
AND ((F.LOT_DATE + A.SHELF_LIFE) - SysDate) / A.SHELF_LIFE < .8
);
子查询可以单独运行,以查找需要更新的所有行;然后IN
仅将更新应用于那些。我们仍然没有桌子结构或关系,所以我只是从你提到的栏目出发;这意味着将更新子查询找到的任何fgmulti
行loc_id
。这可能太宽泛了。如果fgmulti
拥有自己的主键,请改用:
UPDATE FGMULTI
SET NO_SHIP = 'Y'
WHERE ID IN (
SELECT F.ID
...