使用查询中的计算字段更新表

Posted

技术标签:

【中文标题】使用查询中的计算字段更新表【英文标题】:Updating a Table using a calculated field in a query 【发布时间】:2020-01-06 20:30:08 【问题描述】:

我有 2 张桌子:

T1:关于某些交易的总体信息

T2:按项目细分交易及其所在的状态(当前“打开”与“关闭”)

我必须运行一个查询,根据 T2 中的状态确定 T1 中交易的总体状态(即,如果有 2 个行项目,1 是“打开”,另一个是“关闭” " 总体状态是"打开",我通过iif 执行此操作:打开-1 关闭-0,按ID 求和,然后如果> 0,则为"打开",否则为"关闭")

我想运行一个更新查询来更新状态列(由 ID 链接)。到目前为止,我已经尝试过:

UPDATE [T1] INNER JOIN [Query1] ON [Query1].[ID] = [T1].[ID] 
SET [Query1].[Overall Status] = [T1].[Overall Status];`

Query1 定义为:

SELECT [T1].[ID], IIf((Sum(IIf([T2].[Status]="Closed",0,1)))=0,"Closed","Open") AS [Overall Status] 
FROM [T1] INNER JOIN [T2] ON [T1].[ID] = [T2].[ID] 
GROUP BY [T1].[ID];

我总是得到错误

“操作必须使用可更新的查询”

不幸的是,这是在 MS Access 中完成的,但任何建议都会很棒!

【问题讨论】:

您是要更新[Query1] 输出中的值还是表[T1] 中的列。目前这正在尝试(并且失败)做前者。 您好,我正在尝试更新表中的值。 @JNevill 查询 1 是 SELECT [T1].[ID], IIf((Sum(IIf([T2].[Status]="Closed",0,1)))=0,"Closed","Open") AS [Overall Status] FROM [T1] INNER JOIN [T2] ON [T1].[ID] = [T2].[ID] GROUP BY [T1].[ID]; @LeeMac 这能回答你的问题吗? Operation must use an updatable query 【参考方案1】:

Update queries 不能在其源中使用基础聚合查询,如您的 Query1 所示。此外,您无法按照SET 子句的指示更新查询中的列。

直到有一天,Access SQL 符合现代的标准 ANSI 规则,例如它的 RDBMS 对等体suggested(请在链接处投票,无需登录),考虑使用 DCount 表达式包裹的域聚合,例如 IIF。但是,这类似于可能会降低性能的相关聚合子查询。

UPDATE [T1]
SET [T1].[Overall Status] = IIF(NZ(DCount("*",
                                          "[T2]", 
                                          "ID='" & [T1].ID & "' AND ([Status]<>'Closed' 
                                                                     AND [Status] IS NOT NULL)")=0,
                                'Closed',
                                'Open')

【讨论】:

嗨!非常感谢,到目前为止,这是最接近工作的。不幸的是,它给了我一个关于类型转换错误的错误。基于一些快速的谷歌搜索,我猜测数据类型不匹配。由于此列几乎没有任何作用,否则我认为最好更改“整体状态”的数据类型以适合您运行的查询。你知道如何解决这个问题吗?(或者现在的数据类型是什么?) T1表中Overall Status的数据类型是什么?它必须是文本才能接收 ClosedOpen 值。如果这不是问题,请尝试将DCount 包装在NZ() 中。见编辑。 更新后数据类型为“短文本”,还是报同样的错误 即使NZ()?两个表的 ID 是否相同类型,最好是整数? 它们都是短文本(我之所以选择它是因为“开放”与“封闭”)为什么是整数? (如果需要,我可以轻松更改它们,因为列当前是空的)我从上面复制了代码,包括 NZ() 并且它仍然给出错误【参考方案2】:

我没有示例数据,但您要查找的查询如下

UPDATE [T1]
INNER JOIN INNER JOIN [Query1] ON [Query1].[ID] = [T1].[ID]
SET [T1].[Overall Status] = [Query1].[Overall Status] 

【讨论】:

很遗憾,这不是 MS Access 中的有效 SQL。 确实@Lee,更正了 MSAccess 的查询 您基本上已经发布了原始问题中包含的 SQL... 可能的问题是 Query1 包含聚合。 对我来说,问题是他正在更新 T1 以及他正在执行的操作:[Query1].[Overall Status] = [T1].[Overall Status]。如果 T1 正在更新,那是 t1 中的一个字段,应该更新而不是相反 你可能是对的 - 我们必须看看 OP 是如何回应的。【参考方案3】:

鉴于现有查询的逻辑,使用域聚合函数(例如 DCountDSum)的一种可能方法可能是首先将状态初始化为 Closed,使用:

update t1 set t1.status = 'Closed'

然后使用以下命令更新t2 中至少存在一条Open 记录的那些:

update t1 inner join t2 on t1.id = t2.id
set t1.status = 'Open'
where t2.status = 'Open'

我相信这会产生预期的结果。

【讨论】:

以上是关于使用查询中的计算字段更新表的主要内容,如果未能解决你的问题,请参考以下文章

MS Access 使用表字段作为查询条件

在 Access 中的查询中使用 DSum 函数中的计算字段

MS SQL更新时变量函数子查询及字段计算顺序探索

MS SQL更新时变量函数子查询及字段计算顺序探索

1、sql查询语句时怎么把几个字段拼接成一个字段?这几个字段是整型的。

update set语句