MS Access:在连接

时间:2016-01-18 14:01:35

标签: sql ms-access

当我将以下查询粘贴到Access 2007中的SQL视图中时:

SELECT ID_Entry, DateVal
FROM (SELECT [Query A].ID_Entry, DateVal
     FROM [Query A] INNER JOIN [Query B] 
     ON [Query A].ID_Entry = [Query B].ID_Entry
     )  AS QueryAJoinB
ORDER BY ID_Entry, DateVal;

它返回一个大的记录集,其最小值ID_Entry为19.我需要根据字段DateVal的值从该记录集中选择记录。 (ID_Entry是一个表索引。DateVal计算为CDate(CleanRegData(<arguments with data from the current record>))。函数CleanRegData()在VBA中定义。)当我在DateVal上放置WHERE条件时,就是这样:

SELECT ID_Entry, DateVal
FROM (SELECT [Query A].ID_Entry, DateVal
     FROM [Query A] INNER JOIN [Query B] 
     ON [Query A].ID_Entry = [Query B].ID_Entry
     )  AS QueryAJoinB
WHERE DateVal = Date()
ORDER BY ID_Entry, DateVal;

查询因CleanRegData()上的错误而崩溃。调试表明使用ID_Entry = 1记录中的参数调用该函数。错误是正确的,因为该记录不包含CleanRegData()所需的数据。这就是使用上述查询的原因 - 在尝试评估之前选择可以评估DateVal的记录。

Query A返回的记录集的值ID_Entry以19开头,但Query B的记录集的所有值均为ID_Entry,从1开始。在这两个查询上应该将记录集减少到只有Query A返回的记录 - 这些记录可以评估DateVal

但似乎将WHERE条件放在字段DateVal上会导致对Query B中的记录进行评估,其中该字段的定义无效。如何仅在连接的记录集上执行WHERE条件,而不是在连接内的查询上执行?

以下是在设计视图中运行的上述第二个查询的图片:

enter image description here

单击“Debug”会将我带到CleanRegData(),其参数值来自ID_Entry = 1的记录,该记录没有CleanRegData()所需的数据,这就是查询的原因坠毁。但是如果我删除DateVal上的条件,查询将返回一个记录集,其中ID_Entry的最低值为19.所以我的问题是,Access如何从{{{{{{{ 1}?该查询中不应提供该记录。或者我不明白是什么让这种情况发生?

1 个答案:

答案 0 :(得分:1)

首先,我要感谢“Damien_The_Unbeliever”,他通过他对我的问题的评论指导我了解问题的根源。像往常一样,一旦你理解了问题,解决方案就在眼前。我不知道他为什么把他的评论作为评论而不是答案。如果他把它们作为答案发布,我已经接受了,但是因为他没有在这里发布我自己的答案所以人们可以知道问题的解决方案。我看到他已经有超过10万的声誉,所以大概他并不关心答案点。

总结Damien的评论,问题是Access错误地将查询的WHERE谓词与子查询的ON子句中的连接条件混合在一起!这导致它尝试评估未定义该字段的记录上的DateVal,从而导致查询崩溃。

以下是关于这个问题的参考资料,第一个由达米恩提供,其他人在我知道要查找的内容后发现了一些研究:

在第四篇参考文献中,“CWeb”的答案给了我如何开发变通方法的线索。我必须做的是将WHERE谓词放在一个iif()中,再次测试连接条件,这可以防止在错误的记录上评估DateVal。这有点笨拙,因为总是有变通方法,但它确实有效。当我这样做时,我不再需要子查询QueryAJoinB,其目的是在评估WHERE之前使连接发生,这没有发生(这是问题)。这是现在有效的查询:

SELECT ID_Entry, DateVal
FROM [Query A] INNER JOIN [Query B] ON [Query A].ID_Entry = [Query B].ID_Entry
WHERE IIf([Query A].[ID_Entry] = [Query B].[ID_Entry], [DateVal] = Date(), False)
ORDER BY ID_Entry, DateVal;

成功是甜蜜的!再次感谢Damien。