问题
I am trying to write a query in MS Access 2013 and the left join is not working correctly. It is acting like a normal join.
Here is what I'm trying to do.
My first table [All Category Types]
has one column [Category Types]
. I am then trying to left join that to a query that has two aggregate fields in it. Virtual Table [Average by Category Type]
is first grouped by Owner, and then by [Category Type]
. Next is a sum field [CountOfIncident: Number]
.
What I want as a result is every item in table [All Category Types]
and then the correct [CountOfIncident: Number] where Owner == "France"
. This is not working as a left join. It is only showing me the values in [All Category Types]
that have a matching record in [Average by Category Type]
.
If I remove Owner from this table, and only group by [Category Type]
, it works just fine. Is there something about having more than one field in the group by clause that does not allow a left join on a query to work correctly?
SELECT [All Category Types].[Category Type],
[Average by Category Type].[CountOfIncident: Number]
FROM [All Category Types]
LEFT JOIN [Average by Category Type]
ON [All Category Types].[Category Type] = [Average by Category Type].[Category Type]
WHERE ((([Average by Category Type].Owner)="France"));
Thank you.
回答1:
[Average by Category Type].Owner = "France"
can only be true for inner joined records. For outer joined records [Average by Category Type].Owner
is null.
So your WHERE
clause turns your outer join into an inner join. Move the condition to the ON
clause:
SELECT
[All Category Types].[Category Type],
[Average by Category Type].[CountOfIncident: Number]
FROM [All Category Types]
LEFT JOIN [Average by Category Type]
ON ([Average by Category Type].[Category Type] = [All Category Types].[Category Type]
AND [Average by Category Type].Owner = "France");
UPDATE: Unlike other DBMS MS Access needs parentheses for the ON
clause: JOIN tablename ON (...)
rather than JOIN tablename ON ...
.
回答2:
Thorsten Kettner's statement is correct that the WHERE clause has essentially turned the statement into the equivalent of an INNER JOIN.
The key to making the LEFT JOIN work is understanding the order in which criteria are applied. JOIN criteria are always applied first, then the WHERE clause is applied after all records are joined. Since in a LEFT JOIN you want all records from the left table regardless of whether the join condition is satisfied, you must ensure that all conditions are applied either BEFORE or as part of the join condition.
If you can get Thorsten's answer to work with all conditions in the join, I suggest that approach. But in case you have problems (highly likely with Access) then you can also apply some of the conditions in a subquery or by adding WHERE criteria within the saved query [Average by Category Type]. Perhaps it is obvious but in context of the above explanation regarding order of execution, the subquery --including any filtering in the WHERE clause-- is completed before the LEFT JOIN is applied.
SELECT
[All Category Types].[Category Type],
AverageFiltered.[CountOfIncident: Number]
FROM [All Category Types]
LEFT JOIN
(SELECT * FROM [Average by Category Type]
WHERE [Average by Category Type].Owner = 'France')
As AverageFiltered
ON [All Category Types].[Category Type] = AverageFiltered.[Category Type];
来源:https://stackoverflow.com/questions/46185315/ms-access-left-join-not-working-correctly