更新有多个表的表字段

时间:2015-05-14 19:25:54

标签: sql oracle

我正在尝试更新我的表格(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

1 个答案:

答案 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,并且因为arinvtlocations之间没有明显的直接链接。如图所示,你可以使用这样的方法:

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仅将更新应用于那些。我们仍然没有桌子结构或关系,所以我只是从你提到的栏目出发;这意味着将更新子查询找到的任何fgmultiloc_id。这可能太宽泛了。如果fgmulti拥有自己的主键,请改用:

UPDATE FGMULTI
SET NO_SHIP = 'Y'
WHERE ID IN (
  SELECT F.ID
...