Access 2007 - 左连接到查询返回#Error而不是Null

时间:2013-06-18 13:39:31

标签: ms-access ms-access-2007 left-join

与此问题类似,但他们的查询问题从未完全解决过:

#Error showing up in multiple LEFT JOIN statement Access query when value should be NULL

当我想要在连接的右侧没有相应记录的左连接时看到Null时,我得到#Error:

Chain               CasesPerMonthPerStore   MonthOfFirstOrder
Naturally           2.3                     5/1/2011
Tom's Market        #Error
Livingstons         #Error
EverClear           3.1                     7/1/2012
Bob's Market        2.66                    5/1/2012
Andy's Exports      #Error
Jamestowns          0.89                    7/1/2012

如果我将数据复制到表中并保持连接到此表,它可以正常工作,所以我认为查询的语法有问题:

SELECT 
    MonthRange.Chain,
    MonthRange.CasesShipped/IIf(MonthsSinceFirstOrder.Months>DateDiff("m",QueryDates.StartDate,QueryDates.EndDate)+1,
                                DateDiff("m",QueryDates.StartDate,QueryDates.EndDate)+1,
                                MonthsSinceFirstOrder.Months)/NumStores.NumberOfStores AS CasesPerMonthPerStore,
    MonthsSinceFirstOrder.MonthOfFirstOrder
FROM 
    QueryDates, 
    (
        MonthRange 
        INNER JOIN 
        NumStores 
            ON MonthRange.Chain=NumStores.Chain
    ) 
    INNER JOIN 
    MonthsSinceFirstOrder 
        ON MonthRange.Chain=MonthsSinceFirstOrder.Chain;

这个SQL返回正确的结果,它只是当它左手连接到它时返回#Errors的行为。

nb中间的奇怪Iif语句检查自第一个订单以来的月数是否大于指定日期范围内包含的月数 - 所以如果日期范围有6个月且第一个订单是在结束日期前9个月,它使用6;如果第一个订单仅在结束日期前4个月,则使用4。

- 编辑更新 -

是的,我逐个查询了查询的元素,这是我可以获得的最简单的同时仍然重新创建左连接错误:

SELECT 
    MonthRange.Chain, 
    DateDiff("m",QueryDates.StartDate,QueryDates.EndDate)+1 AS CasesPerMonthPerStore
FROM 
    QueryDates, 
    MonthRange;

这就是我加入它的方式:

SELECT 
    Chains.Chain, 
    ErrorQuery.CasesPerMonthPerStore
FROM 
    Chains 
    LEFT JOIN 
    ErrorQuery 
        ON Chains.Chain=ErrorQuery.Chain;

这个SQL中的任何内容都有错误吗?

3 个答案:

答案 0 :(得分:2)

虽然查询应该根据连接类型返回Null,正如Allen Browne在他的文章Bug: Outer join expressions retrieved wrongly中所述,

“相反,它表现得好像[JET查询优化器]在从较低级别查询返回结果后正在评估表达式。”

因此,您必须使用一个表达式选择计算字段,如果连接的右侧与左侧不匹配,该表达式将计算为Null。

使用您的简化代码作为示例:

SELECT 
Month.Chain,
DateDiff("m",QueryDates.StartDate,QueryDates.EndDate)+1 AS CasesPerMonthPerStore
FROM
QueryDates,
MonthRange;

SELECT
Chains.Chain,
IIf(IsNull(ErrorQuery.Chain),Null,ErrorQuery.CasesPerMonthPerStore)
FROM
Chains
LEFT JOIN
ErrorQuery
ON Chains.Chain=ErrorQuery.Chain;

答案 1 :(得分:1)

看起来它可能与Access中的已知错误有关,因此它会在计算字段的外连接上出错:

http://allenbrowne.com/BugOuterJoinExpression.html

http://allenbrowne.com/bug-10.html

那就去看看我是否可以重新调整子查询来以某种方式伪装计算字段。

访问。 :)

答案 2 :(得分:0)

这很老了,但是我找到了解决方法,希望对您有所帮助。我在右侧查询中遇到了相同的问题,但是我也有一个并行的右侧查询,该查询具有相似的数据源和派生,在左联接中可以正常工作。区别在于,在工作右侧和具有简单计算字段的基础查询之间存在UNION查询。因此,我通过在空白表中创建具有相同字段的空表,并与该表和原始右侧查询创建联合,从而在麻烦的右侧查询和最终查询之间添加了UNION查询。运作良好。根据Wilskt和Allen Browne的信息,我认为UNION迫使Jet推迟评估。