三表关联SELECT查询语句问题:无地址属性记录时如何返回用户及地址数据
嘿,这个问题我太熟了——你现在用的是默认的INNER JOIN(也就是隐式的,因为没写LEFT/RIGHT这类关键词),这种JOIN的特性就是必须所有关联表都有匹配记录才会返回行,一旦s_user_addresses_attributes里没对应的数据,整行就被过滤掉了。
要解决这个问题,只需要把和地址属性表的关联改成LEFT JOIN,同时调整关联条件的位置(避免WHERE子句过滤掉NULL结果),修改后的SQL如下:
SELECT * FROM s_user AS a JOIN s_user_addresses AS b ON b.user_id = a.id AND b.id != IF(((SELECT COUNT(*) FROM s_user_addresses WHERE user_id = a.id) > 1), a.default_billing_address_id, 0) LEFT JOIN s_user_addresses_attributes AS c ON b.id = c.address_id WHERE a.id = 416 ORDER BY a.id;
关键改动说明:
- LEFT JOIN替代默认INNER JOIN:
LEFT JOIN s_user_addresses_attributes AS c会保留s_user和s_user_addresses的所有匹配记录,哪怕s_user_addresses_attributes里没有对应address_id的行,此时属性表的字段会以NULL值填充。 - 关联条件移到ON子句:把
s_user_addresses和s_user_addresses_attributes的关联条件b.id = c.address_id放在LEFT JOIN的ON里,而不是WHERE中——如果放在WHERE里,会自动过滤掉c.address_id为NULL的行,相当于又变回了INNER JOIN的效果。 - 规范显式JOIN写法:把
s_user和s_user_addresses的关联条件也移到ON子句,这是SQL的标准写法,比把所有条件堆在WHERE里更清晰,也能避免逻辑混淆。
这样修改后,就算没有地址属性记录,用户和地址的数据也能正常返回啦。
内容的提问来源于stack exchange,提问作者meDom
相关产品推荐
相关产品推荐

