If you don't need the other data from the NETWORK_STATUS table, how about:
select *
from dbo.NETWORK AS n
inner join dbo.vwNETWORK_KEYMSTN AS km
on n.Network_ID = km.Network_ID
inner join dbo.vwAPPROVAL_LATEST AS a
on n.Network_ID = a.Network_ID
inner join dbo.APPROVAL_VINTAGE AS av
on a.Approval_ID = av.Approval_ID
and km.Milestone_Type_ID = av.Milestone_Type_ID
inner join dbo.NETWORK_MILESTONE AS m
on A.Approval_ID = m.Approval_ID
and km.Milestone_Type_ID = m.Milestone_Type_ID
inner join dbo.REF_MILESTONE AS rm
on km.Milestone_Type_ID = rm.Milestone_Type_ID
WHERE EXISTS
(
SELECT 1 FROM dbo.NETWORK_STATUS
WHERE Network_ID = n.Network_ID
and Status_Type_ID = 2
--and Status_Type_ID = rm.Status_Type_ID
);
As JNK said, for an INNER JOIN
, these are going to be the same. You can prove it by comparing actual (don't bother with estimated) execution plans. In this case, they are exactly the same (click to enlarge):
Personally, I like to keep the join conditions and the filter conditions separate. Join conditions go in the ON
clause, and filter conditions go in the WHERE
clause. This is one of the primary benefits of having explicit INNER JOIN
syntax in the first place, which helps to reduce the risk of returning too many rows because of not enough (or even no) join criteria inherent in old-style joins (where filter and join criteria are thrown together) - see this blog post for more details.
JNK is also right though that you need to be careful when you're talking about OUTER JOIN
. A simple example:
CREATE TABLE dbo.a(id INT);
CREATE TABLE dbo.b(id INT, name SYSNAME);
INSERT dbo.a(id) VALUES(1),(2),(3);
INSERT dbo.b(id) VALUES(2,N'a'),(3,N'b');
SELECT a.id, b.name
FROM dbo.a
LEFT OUTER JOIN dbo.b
ON a.id = b.id
AND b.name LIKE N'b%';
SELECT a.id, b.name
FROM dbo.a
LEFT OUTER JOIN dbo.b
ON a.id = b.id
WHERE b.name LIKE N'b%';
--^^^^^ only difference
DROP TABLE dbo.a, dbo.b;
Results:
id name
---- ----
1 NULL
2 NULL
3 b
id name
---- ----
3 b
As you can see from the results, the first query still returns all three rows from a
(as you would expect), however the second query turns the OUTER JOIN
into an INNER JOIN
, and only returns the rows from a
with a match from b
on all conditions. You may want one behavior or the other, so neither of these is "worse" or "wrong," it's just important to understand the different functionality so you know to write the query to get the results you are after.
Best Answer
It can do
In the plan I got the first row matched the
LIKE 'John%'
predicate and the scan againstcustomer_emails
was not executed at all.However your question is phrased as
That would imply that the simpler WHERE clause is evaluated in its entirety and only if that fails is the second one evaluated.
For
Three rows were processed before one was found matching
LIKE 'George%'
and there were two ensuing scans oncustomer_emails
Rewriting as follows...
... happens to give a plan where the operators in the shaded area for the
IN
part don't get executed if the simpler predicate returns a row but this plan isn't guaranteed.