使用查询中的计算字段更新表
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的数据类型是什么?它必须是文本才能接收 Closed 和 Open 值。如果这不是问题,请尝试将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】:
鉴于现有查询的逻辑,使用域聚合函数(例如 DCount
或 DSum
)的一种可能方法可能是首先将状态初始化为 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'
我相信这会产生预期的结果。
【讨论】:
以上是关于使用查询中的计算字段更新表的主要内容,如果未能解决你的问题,请参考以下文章
在 Access 中的查询中使用 DSum 函数中的计算字段