我的数据库有两个表:users
,users_addresses
和countries
。
当我选择用户记录并将其绑定到模型时,我使用以下语句:
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
我遇到的问题是,如果表users_addresses
不包含用户的相应记录,那么我得到一个空结果。如果有记录 - 它应该只返回一个标记为default
= 1的记录,但显然最好确保它总是返回一个以防万一,因为任何原因,一个用户将有多个地址被标记默认情况下。
所以我的问题是 - 我怎么能确保即使users_addresses
表中没有相应的记录,我仍然会得到至少用户记录以及如何确保查询总是只匹配一个地址记录
非常感谢任何帮助。
答案 0 :(得分:2)
LEFT JOIN
将包含左表中的条目。
但是,在您的情况下,您会按a.default = 1
过滤,删除没有默认地址的条目。
为避免这种情况,您需要加入子查询
LEFT JOIN (
SELECT * FROM user_adresses
WHERE `default` = 1
) a
ON a.user = u.id
使用此选项,您可以在子选择中使用GROUP BY user
将每个用户最多限制为一个“默认”地址。
或者你可以使用a.default = 1
作为连接条件而不是where条件,即
LEFT JOIN user_addresses a
ON a.user = u.id and a.default = 1
不是100%肯定最后一个建议,但我相信这会奏效。
编辑:你显然也有@steinmas建议的选项,即在默认情况下扩展过滤器以接受 null 值。
为了确保您最多能够获得一个用户的默认地址,您很可能在某个时候需要GROUP BY user
命令
答案 1 :(得分:1)
尝试将WHERE子句更改为:
WHERE (`a`.`default` = 1 OR `a`.`default` IS NULL)
AND `u`.`id` = 3
答案 2 :(得分:0)
这是按照定义
LEFT JOIN关键字返回左表(table1)中的所有行, 使用右表(table2)中的匹配行。结果为NULL 在没有匹配的情况下在右侧。
如果您可以重新组织查询