更新子查询(WHERE/FROM)

Posted

技术标签:

【中文标题】更新子查询(WHERE/FROM)【英文标题】:UPDATE with Subqueries (WHERE/FROM) 【发布时间】:2019-01-14 17:52:58 【问题描述】:

我正在尝试从子查询更新名为 [Assets] 的表中的 Yes/No 字段(已密封)。

子查询结果包含来自 [Assets] 的 ID 和要更新的字段的期望结果。

我尝试了几个选项,包括 WHERE 或 FROM 子句,但都无法获得合适的结果。

下面是基本的更新语句和子查询。非常感谢任何建议。

UPDATE [Assets] SET Sealed = IsSealed

SELECT y.Asset AS Asset, 
       IIF(y.TotalSeals>0,Yes,No) AS IsSealed
FROM (
SELECT x.Asset, 
       SUM(IIF(x.BOMTypes="Seal",1,0)) AS BOMSeals, 
       SUM(IIF(x.MatMovTypes="Seal",1,0)) AS MMSeals, 
       SUM(IIF(x.POTypes="Seal",1,0)) AS POSeals, 
       (BOMSeals + MMSeals + POSeals) AS TotalSeals 
FROM (
SELECT [Data - Assets].ID AS Asset, 
       [Data - Inventory].Type AS BOMTypes, 
       NULL AS MatMovTypes, NULL AS POTypes, NULL AS TotalSeals 
FROM [Data - Inventory] INNER JOIN ([Data - Assets] INNER JOIN [Data - BOM] 
ON [Data - Assets].ID = [Data - BOM].Asset) 
ON [Data - Inventory].ID = [Data - BOM].Component 

UNION ALL 
SELECT [Data - Assets].ID AS Asset, NULL AS BOMTypes, 
       [Data - Inventory].Type AS MatMovTypes, 
       NULL AS POTypes, NULL AS TotalSeals 
FROM ([Data - Assets] INNER JOIN [Data - WO] 
ON [Data - Assets].ID = [Data - WO].Asset) 
INNER JOIN ([Data - Inventory] INNER JOIN [Data - MatMov] 
ON [Data - Inventory].ID = [Data - MatMov].Component) 
ON [Data - WO].ID = [Data - MatMov].WorkOrder 

UNION ALL 
SELECT [Data - Assets].ID AS Asset, 
       NULL AS BOMTypes, NULL AS MatMovTypes, 
       [Data - Inventory].Type  AS POTypes, NULL AS TotalSeals 
FROM ([Data - Assets] INNER JOIN [Data - WO] 
ON [Data - Assets].ID = [Data - WO].Asset) 
INNER JOIN ([Data - Inventory] INNER JOIN [Data - PO] 
ON [Data - Inventory].ID = [Data - PO].Component) 
ON [Data - WO].ID = [Data - PO].WorkOrder  
)  AS x 
GROUP BY x.Asset
)  AS y;

【问题讨论】:

【参考方案1】:

假设您的表 Assets 包含一个字段 Asset 对应于您的子查询中的 y.Asset 列,那么我建议如下:

update assets a inner join
(
    select y.asset, iif(y.totalseals > 0, Yes, No) as issealed
    from 
    (
       ***TLDR
    ) y
) t on a.asset = t.asset 
set a.sealed = t.issealed

这假定您的子查询不包含任何形式的聚合,否则查询将不可更新。

如果您的子查询包含聚合,您可以使用域聚合函数,例如 DCountDSum(取决于子查询执行的操作)。

【讨论】:

啊,我的子查询实际上包括聚合。你能解释一下为什么聚合是不可更新的吗? @AdamB 因为记录之间不再存在一对一的关系,JET 数据库引擎有这样的限制。我已经用另一个建议更新了我上面的答案。 我已经更新了我的帖子以包含完整的代码,包括聚合。您能否进一步解释如何实现域聚合以达到预期的结果?原谅我,我对 SQL 很陌生。

以上是关于更新子查询(WHERE/FROM)的主要内容,如果未能解决你的问题,请参考以下文章

使用子查询更新语句

12W学习笔记——独立子查询,更新,删除,建立视图

更新期间子查询返回多行

具有相关子查询的更新查询不能通过表别名

在 Sql Server 中使用子查询更新查询

更新语句给子查询错误的结果[重复]