Reputation: 115
I have wrote 2 SQL statements.
SELECT
customers.CustomerID,
orders.OrderID
FROM customers LEFT JOIN orders ON customers.CustomerID =
orders.CustomerID AND orders.EmployeeID=4
WHERE orders.OrderID IS NULL;
And
SELECT
customers.CustomerID,
orders.OrderID
FROM customers LEFT JOIN orders ON customers.CustomerID =
orders.CustomerID AND orders.EmployeeID=4 AND orders.OrderID IS NULL;
The 1st one returns 16 entries, which is correct (per the solution). The 2nd one returns 91 entries. I am using Northwind for mysql version. I read from somewhere that placing condition in JOIN statement is equivalent to doing that in WHERE statement. However, here I can see the difference.
Upvotes: 2
Views: 83
Reputation: 48875
The second query will return more rows. Why? Read on:
Second query
The second query will match orders
rows to customers
rows using the predicate:
customers.CustomerID = orders.CustomerID AND orders.EmployeeID=4 AND orders.OrderID IS NULL
Unmatched customers
rows will always show up in the result.
First query
Now, the first query will match orders
rows to customers
rows using the predicate:
customers.CustomerID = orders.CustomerID AND orders.EmployeeID=4
Then it will filter out rows where orders.OrderID
is null, removing customer
rows that do not fullfil this last predicate, therefore producing less rows. Unmatched customers rows may not show up in the result.
Example:
create table customers (
CustomerId int
);
create table orders (
OrderId int,
CustomerId int,
EmployeeId int
);
insert into customers (CustomerId) values (1), (2), (3);
insert into orders (OrderId, CustomerId, EmployeeId) values
(1001, 1, 3),
(1002, 1, 4),
(1003, 2, 1);
The first query returns:
CustomerId OrderId
---------- ----------------
2 <null>
3 <null>
while the second query returns:
CustomerId OrderId
---------- ----------------
1 <null>
2 <null>
3 <null>
Upvotes: 1
Reputation: 1271
This is to do with the order execution on the statements and the fact you’re using a LEFT JOIN
.
A LEFT JOIN
will keep all the values from the left side intact, combining only values from the right side that match conditions.
A WHERE
clause operates on the query as a whole (in this case).
Query 1:
Query 2:
The only time a WHERE
is really analogous to a JOIN
is something like a INNER JOIN
, which gets only the relevant values from both left and right sides. I think at least, it has been a while since I flexed the SQL muscles.
Edit - count the number of rows (nothing else) in your customers
table, it should return 91 as well.
Upvotes: 2
Reputation: 3970
This could be because of the order in which the Sql query runs FROM and JOIN s. The FROM clause, and subsequent JOIN s are first executed then WHERE and lastly SELECT.
In second case all the join conditions ran together but in the first case the where clause made the difference after joining the data and filtering not at the same time but as a whole after joining.
Upvotes: 0