Access数据库UPDATE关联查询含义咨询及SQL Server兼容性疑问
你的Access UPDATE语句详解与SQL Server兼容性问题
我来帮你拆解这条Access特有的SQL语句,顺便说明为什么它在SQL Server里跑不通~
一、原语句的具体含义
先把你的原语句贴出来方便对照:
UPDATE A INNER JOIN (B INNER JOIN C ON B.Control = C.Control) ON A.ClientType = B.Type SET C.EstTime = ([A].[AvgTime])*60;
这条语句是Access Jet SQL的多表关联更新写法,核心逻辑可以拆成3步:
第一层关联:匹配B和C表
先通过B.Control = C.Control这个条件,把表B和表C做内连接(INNER JOIN)——只有两边Control字段值完全相同的记录,才会被保留到后续的操作集合里。第二层关联:匹配A表与前序结果
把第一步得到的B+C关联结果,再和表A做内连接,关联条件是A.ClientType = B.Type——这一步会进一步筛选出「A的ClientType等于B的Type」且「B的Control等于C的Control」的所有记录组合。执行更新操作
对最终匹配到的表C的记录,把EstTime字段的值设置为对应A表记录的AvgTime值乘以60(大概率是做单位转换,比如把分钟转成秒,或者小时转成分钟)。
简单总结:找到同时满足两个关联条件的A、B、C表记录,用A的AvgTime乘以60来更新C的EstTime字段。
二、为什么SQL Server不支持这个写法?
这是因为Access的Jet SQL和SQL Server的T-SQL在多表更新语法上有本质差异:
- Access允许在UPDATE语句里直接嵌套INNER JOIN的关联结构;
- 而SQL Server的多表更新需要用
UPDATE ... FROM ... JOIN的语法结构,或者通过子查询来实现关联。
改成SQL Server兼容的写法示例
你可以把原语句改成下面两种形式之一,就能在SQL Server里正常执行了:
写法1:使用UPDATE + FROM + JOIN
UPDATE C SET C.EstTime = A.AvgTime * 60 FROM A INNER JOIN B ON A.ClientType = B.Type INNER JOIN C ON B.Control = C.Control;
写法2:使用子查询+EXISTS(避免重复更新风险)
如果担心存在一对多关联导致重复更新,可以用这种更严谨的写法:
UPDATE C SET EstTime = ( SELECT A.AvgTime * 60 FROM A INNER JOIN B ON A.ClientType = B.Type WHERE B.Control = C.Control ) WHERE EXISTS ( SELECT 1 FROM A INNER JOIN B ON A.ClientType = B.Type WHERE B.Control = C.Control );
内容的提问来源于stack exchange,提问作者urlreader




