简体   繁体   English

MySQL返回记录,其中左联接表没有记录

[英]MySQL return record where left joined table has no record

I'm having a database with two tables: users , users_addresses and countries . 我有两个表的数据库: usersusers_addressescountries

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. 我遇到的问题是,如果表users_addresses不包含该用户的相应记录,那么我将得到一个空结果。 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. 如果有一条记录-它仅应返回一个标记为default = 1的记录,但是显然,最好还是确保它始终只返回一个,以防万一,由于某种原因,一个用户将有多个标记为默认地址的用户。

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. 所以我的问题是-我怎么能确保即使users_addresses表中没有相应的记录,我仍将至少获得用户记录,以及如何确保查询始终只匹配一个地址记录。

Any help would be very much appreciated. 任何帮助将不胜感激。

LEFT JOIN will include entries from the left table if there's no corresponding entry in the right tables. 如果右侧表中没有相应的条目,则LEFT JOIN将包括左侧表中的条目。

However in your case you then filter by a.default = 1 which remove entries with no default address. 但是,根据您的情况,然后按a.default = 1进行过滤,这将删除没有默认地址的条目。

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. 使用此选项,您可以通过在子选择中使用GROUP BY user来限制每个用户最多一个“默认”地址。

Or you could use the a.default = 1 as a join condition and not a where condition, ie 或者您可以使用a.default = 1作为连接条件,而不是where条件,即

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. 并非100%可以肯定最后的建议,但我非常有信心这样做。

Edit: and you obviously also have the option suggested by @steinmas, ie extending the filter on default to accept also null values. 编辑:显然,您也可以使用@steinmas建议的选项,即在默认情况下扩展过滤器以接受值。

To ensure you get at most one default address by user, you'll most likely need a GROUP BY user command at some point 为确保每个用户最多获得一个默认地址,在某个时候您很可能需要GROUP BY user命令

Try changing your WHERE clause to this: 尝试将WHERE子句更改为此:

WHERE (`a`.`default` = 1 OR `a`.`default` IS NULL)
AND `u`.`id` = 3

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). LEFT JOIN关键字返回左侧表(table1)中的所有行,以及右侧表(table2)中的匹配行。 The result is NULL in the right side when there is no match. 如果没有匹配项,则结果在右侧为NULL。

If you can reorganize the query 如果可以重新组织查询

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM