Reputation: 481
I currently have the following, and I've read that it's generally better to avoid "IN" and use "EXISTS" instead (1, 2). Though I've read that EXISTS is faster and more consistent, I don't think I've grasped entirely why that is, or how I would go about rewriting this to use EXISTS instead.
SELECT qryAccountNamesConcat.AccountID, qryAccountNamesConcat.AccountName, qryAccountNamesConcat.JobTitle
FROM qryAccountNamesConcat
WHERE (((qryAccountNamesConcat.AccountID) In (
SELECT AccountID
FROM tblAccount
WHERE AccountTypeID IN (1, 2))
Or
qryAccountNamesConcat.AccountID In (
SELECT ChildAccountID
FROM qryAccJunctionDetails
WHERE ParentAccountTypeID IN (1, 2))
));
Basically, Where AccountTypeID = 1 or 2 this is a trade or private customer account, so I am looking for accounts which are, or which are children of (usually employees of) customer accounts.
Upvotes: 0
Views: 698
Reputation: 3938
Depending on the data, either one or the other can be the fastest; so you have to try it with your own data to know which one will be the fastest for your query.
As for the inconsistency for IN, there are problems when there is the possibility of having a Null value. For example, while the following first query will return a row; the other two won't return anything:
Select 1 where 1 in (1, Null);
Select 1 where 2 Not in (1, Null);
Select 1 where Null in (1, Null);
This example is for SQL Server. For MS Access, I think that you have to specify a FROM MyTable
statement to try it. (And of course, the number of rows returned by the first query will be equal to the total number of rows in the table MyTable.)
Upvotes: 1
Reputation: 1270573
I do not know if exists
is better than in
for MS Access (although exists
often performs better than in
in other databases). However, you would write it as:
SELECT anc.AccountID, anc.AccountName, anc.JobTitle
FROM qryAccountNamesConcat as anc
WHERE EXISTS (SELECT 1
FROM tblAccount as a
WHERE a.AccountTypeId in (1, 2) and anc.AccountID = a.AccountID
) OR
EXISTS (SELECT 1
FROM qryAccJunctionDetails as jd
WHERE jd.ParentAccountTypeID in (1, 2) and jd.ChildAccountID = anc.AccountID
);
For best performance, you will want an index on tblAccount(AccountId, AccountTypeId)
and qryAccJunctionDetails(ChildAccountID, ParentAccountTypeID)
.
Upvotes: 2