Reputation: 6796
I remember this rule of thumb from back in college that if you put a left join in a SQL query, then all subsequent joins in that query must also be left joins instead of inner joins, or else you'll get unexpected results. But I don't remember what those results are, so I'm wondering if maybe I'm misremembering something. Anyone able to back me up on this or refute it? Thanks! :)
For instance:
select * from customer
left join ledger on customer.id= ledger.customerid
inner join order on ledger.orderid = order.id -- this inner join might be bad mojo
Upvotes: 2
Views: 1220
Reputation: 507
You remember correctly some parts of it!
The thing is, when you chain join tables like this
select * from customer
left join ledger on customer.id= ledger.customerid
inner join order on ledger.orderid = order.id
The JOIN is executed sequentialy, so when customer left join ledger
happens, you are making sure all joined keys from customer return (because it's a left join! and you placed customers to the left).
Next,
The results of the former JOIN are joined with order
(using inner join), forcing the "the first join keys" to match (1 to 1) with the keys from order
so you will end up only with records that were matched in order
table as well
Bad mojo? it really depends on what you are trying to accomplish.
If you want to guarantee all records from customers
return, you should keep "left joining" to it.
You can, however, make this a little more intuitive to understand (not necessarily a better way of writing SQL!) by writing:
SELECT * FROM
(
(SELECT * from customer) c
LEFT JOIN
(SELECT * from ledger) l
ON
c.id= l.customerid
) c_and_l
INNER JOIN (OR PERHAPS LEFT JOIN)
(SELECT * FROM order) as o
ON c_and_l.orderid (better use c_and_l.id as you want to refer to customerid from customers table) = o.id
So now you understand that c_and_l is created first, and then joined to order (you can imagine it as 2 tables are joining again)
Upvotes: 2
Reputation: 1270301
Not that they have to be. They should be (or perhaps a full join
at the end). It is a safer way to write queries and express logic.
Your query is:
select *
from customer c left join
ledger l
on c.id = l.customerid inner join
order o
on l.orderid = o.id
The left join
says "keep all customers, even if there is no matching record in ledger
. The second says, "I have to have a matching ledger record". So, the inner join
converts the first to an inner join
.
Because you presumably want all customers, regardless of whether there is a match in the other two tables, you would use a left join
:
select *
from customer c left join
ledger l
on c.id = l.customerid left join
order o
on l.orderid = o.id
Upvotes: 4