Access 2007 - Left Join to a query returns #Error instead of Null
Similar to this question, but their problem with the query was never fully solved:
#Error showing up in multiple LEFT JOIN statement Access query when value should be NULL
I get #Error when I'm expecting to see a Null when doing a left join where there is no corresponding record on the right hand side of the join:
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
It works fine if I copy the data into a table and left join to this table, so I assume there is something wrong in the syntax of the query:
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;
This SQL returns the correct results, it's just its behaviour when Left Joining to it that is returning #Errors.
nb the strange Iif statement in the middle checks to see if the number of months since the first order is greater than the number of months included in the specified date range - so if the date range has 6 months and the first order was 9 months before the end date, it uses 6; if the first order was only 4 months before the end date, it uses 4.
-- EDIT UPDATE --
Right, I took elements of the query out one by one, and this is the simplest I can get whilst still recreating the left joining error:
SELECT
MonthRange.Chain,
DateDiff("m",QueryDates.StartDate,QueryDates.EndDate)+1 AS CasesPerMonthPerStore
FROM
QueryDates,
MonthRange;
And this is how I'm left joining to it:
SELECT
Chains.Chain,
ErrorQuery.CasesPerMonthPerStore
FROM
Chains
LEFT JOIN
ErrorQuery
ON Chains.Chain=ErrorQuery.Chain;
Does anything in this SQL look wrong?
While the query should return Null based on the join type, as Allen Browne states in his article, Bug: Outer join expressions retrieved wrongly,
"Instead, it behaves as if [the JET query optimizer] is evaluating the expression after it has returned the results from the lower-level query."
Consequently, you must select the calculated field using an expression that will evaluate to Null if the right-side of the join doesn't match the left-side.
Using your pared-down code as an example:
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;
It's looking like it could be to do with a known bug in Access, whereby it makes mistakes on outer joins with calculated fields:
http://allenbrowne.com/BugOuterJoinExpression.html
and
http://allenbrowne.com/bug-10.html
So going to see if I can rejig the subqueries to disguise the calculated fields somehow.
I love Access. :)