A "NOT EXISTS" clause is useful here:
SELECT <whatever fields you want>
FROM ACCOUNT
WHERE NOT EXISTS(SELECT TRIALBAL FROM [Dimensions] WHERE
[Dimensions].[accountnumber] = [Account].[accountnumber])
But do be aware that NOT EXISTS (and NOT IN) is not well-optimized
by the Jet/ACE query pre-processor -- it will often fail to use
the indexes on both sides of the comparison, resulting in major
performance problems. If the query can be done with a JOIN, it's
preferable, as JOINs always utilize indexes to the greatest degree
possible.
Good point, David. In this case the JOIN approach is a bit tricky
since you need to join to a query with criteria. It would be
simplest to create a query qryTRIALBAL as
SELECT accountnum FROM Dimensions WHERE Dimension = "TRIALBAL";
and then use an unmatched query:
SELECT Account.<whatever fields>
FROM ACCOUNT LEFT JOIN qryTrialbal
ON Account.accountnum = qryTrialbal.Accountnum
WHERE qryTrialbal.Accountnum IS NULL;
It's not all that tricky -- you just use a derived table subquery:
SELECT Account.<whatever fields>
FROM ACCOUNT LEFT JOIN [SELECT TRIALBAL FROM Dimensions WHERE
Dimensions.accountnumber = Account.accountnumber]. As Trialbal
ON Account.accountnum = Trialbal.Accountnum
WHERE qryTrialbal.Accountnum IS NULL;
I do this all the time in dynamic SQL.
However, note that if you have fields with reserved words in the
names or spaces or other characters that require the square
brackets, you can't use this, because the square brackets required
for the derived table in Jet/ACE's SQL 89 dialect for derived tables
cannot have internal square brackets.
If you're working in SQL 92 mode, you can use standard parens
(without the silly trailing period):
SELECT Account.<whatever fields>
FROM ACCOUNT LEFT JOIN (SELECT TRIALBAL FROM Dimensions WHERE
Dimensions.accountnumber = Account.accountnumber). As Trialbal
ON Account.accountnum = Trialbal.Accountnum
WHERE qryTrialbal.Accountnum IS NULL;
When working in SQL 89 mode (i.e., Access's default), you can also
write your SQL in this form and the Access QBE will convert it to
it's idiosyncratic dialect, but if you've got internal square
brackets, it will break, nonetheless.