I have 2 tables with a structure similar with this:
table: user
fields: id, active_office_address_id (this can be 0)
table: user_address
fields: id, user_id, type (home, office)
A user can have a "home" address (not mandatory) and multiple "office" addresses. I have a join to get a user address, but I want that if the user have a "home" address to get that address, not "office" address.
So, how can I get "home" address if exists, and only if that not exists to get "office" address. (In reality the query is much more complicated and the join is done on 4-5 tables)
SELECT * FROM user LEFT JOIN user_address ON (user.id = address.user_id AND
(user_address.type = "home" OR user.active_office_address_id = user_address.id))
group by user.id
It doesn't matter.
The order doesn't matter for INNER joins but the order matters for (LEFT, RIGHT or FULL) OUTER joins. Outer joins are not commutative.
The LEFT JOIN query is slower than the INNER JOIN query because it's doing more work.
“Is there a performance difference between putting the JOIN conditions in the ON clause or the WHERE clause in MySQL?” No, there's no difference. The following queries are algebraically equivalent inside MySQL and will have the same execution plan.
You can use COALESCE()
and join to your address table twice:
SELECT user.id
,COALESCE(home.address, office.address) AS Address
FROM user
LEFT JOIN user_address AS home
ON user.id = home.user_id
AND home.type = "home"
LEFT JOIN user_address AS office
ON user.active_office_address_id = office.user_id
GROUP BY user.id
Two left joins and a case statement will give you the address id you want.
SELECT user.*,CASE WHEN home_addr.id IS NOT NULL THEN home_addr.id ELSE ofc_addr.id END AS addr_id
FROM user
LEFT JOIN user_address AS home_addr
ON (user.id = home_addr.user_id AND home_addr.type = 'home')
LEFT JOIN user_address AS ofc_addr
ON (user.active_office_address_id = ofc_addr.id)
You could feed this back in as a sub-select for a particular user:
SELECT * FROM user LEFT JOIN user_address
WHERE user.id = ?
AND user_address.user_id = user.id
AND user_address.id IN
(SELECT CASE WHEN home_addr.id IS NOT NULL THEN home_addr.id ELSE ofc_addr.id END AS addr_id
FROM user
LEFT JOIN user_address AS home_addr
ON (user.id = home_addr.user_id AND home_addr.type = 'home')
LEFT JOIN user_address AS ofc_addr
ON (user.active_office_address_id = ofc_addr.id)
WHERE user.id = ?)
This assumes that only one home address exists per user.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With