Reputation: 5311
I'm having a database with two tables: users
, users_addresses
and countries
.
When I'm selecting user record and binding it to the model I'm using the following statement:
SELECT
`u`.`id`, `u`.`first_name`, `u`.`last_name`,
`a`.`address_1`, `a`.`address_2`,
`a`.`town`, `a`.`region`, `a`.`post_code`, `a`.`country`,
`c`.`name` AS `country_name`,
`c`.`eu` AS `eu_member`
FROM `users` `u`
LEFT JOIN `users_addresses` `a`
ON `a`.`user` = `u`.`id`
LEFT JOIN `countries` `c`
ON `c`.`id` = `a`.`country`
WHERE `a`.`default` = 1
AND `u`.`id` = 3
The problem I'm having is that if table users_addresses
does not contain corresponding record for the user then I get an empty result. If there is a record - it should only return one marked as default
= 1, but obviously it would be better to ensure that it always returns just one in case, for any reason one user will have more than one addresses marked as default.
So my question is - how could I make sure that even if there is no corresponding record in the users_addresses
table I will still get at least user record and how to ensure that query will always match just one address record.
Any help would be very much appreciated.
Upvotes: 0
Views: 86
Reputation: 1056
LEFT JOIN
will include entries from the left table if there's no corresponding entry in the right tables.
However in your case you then filter by a.default = 1
which remove entries with no default address.
To avoid that, you will need to either join with a subquery
LEFT JOIN (
SELECT * FROM user_adresses
WHERE `default` = 1
) a
ON a.user = u.id
With this option you can limit to at most one 'default' address per user by using a GROUP BY user
in the subselect.
Or you could use the a.default = 1
as a join condition and not a where condition, i.e.
LEFT JOIN user_addresses a
ON a.user = u.id and a.default = 1
Not 100% sure about that last suggestion, but I'm pretty confident this would work.
Edit: and you obviously also have the option suggested by @steinmas, i.e. extending the filter on default to accept also null values.
To ensure you get at most one default address by user, you'll most likely need a GROUP BY user
command at some point
Upvotes: 2
Reputation: 4666
This is by definition
The LEFT JOIN keyword returns all rows from the left table (table1), with the matching rows in the right table (table2). The result is NULL in the right side when there is no match.
If you can reorganize the query
Upvotes: 0
Reputation: 398
Try changing your WHERE clause to this:
WHERE (`a`.`default` = 1 OR `a`.`default` IS NULL)
AND `u`.`id` = 3
Upvotes: 1