MySQL实现两表合并:将同一订单的账单地址与收货地址合并为单行
MySQL实现两表合并:将同一订单的账单地址与收货地址合并为单行
嘿,我完全懂你现在的困扰——想把分散在两张表里的订单账单地址和收货地址合并成一行,每个订单只显示一条记录对吧?其实用MySQL的自连接就能轻松解决这个问题,咱们来一步步实现:
核心思路
我们需要把order_address表连接两次:
- 第一次连接用来匹配账单地址:关联条件是订单表的
billing_address_id等于地址表的id - 第二次连接用来匹配收货地址:关联条件是订单ID和地址表的
order_id一致,并且地址ID不等于账单地址ID(排除掉已经匹配过的账单地址)
完整SQL语句
SELECT o.order_number, billing_addr.first_name, billing_addr.last_name, billing_addr.street, billing_addr.zipcode, billing_addr.city, shipping_addr.first_name AS ship_first_name, shipping_addr.last_name AS ship_last_name, shipping_addr.street AS ship_street, shipping_addr.zipcode AS ship_zipcode, shipping_addr.city AS ship_city FROM `order` o LEFT JOIN order_address billing_addr ON o.billing_address_id = billing_addr.id LEFT JOIN order_address shipping_addr ON o.id = shipping_addr.order_id AND shipping_addr.id != o.billing_address_id ORDER BY o.order_number;
代码解释
- 用
LEFT JOIN而不是INNER JOIN是为了确保即使某个订单只有账单地址(比如你的订单1001),也能正常显示,收货地址字段会以NULL填充 - 给两次连接的地址表分别起别名
billing_addr和shipping_addr,方便区分不同类型的地址 - 对收货地址的字段添加
ship_前缀,和账单地址字段做区分
测试结果
用你提供的示例数据运行这个SQL,就能得到你想要的输出:
| order_number | first_name | last_name | street | zipcode | city | ship_first_name | ship_last_name | ship_street | ship_zipcode | ship_city |
|---|---|---|---|---|---|---|---|---|---|---|
| 1001 | John | Doe | Washington Street 2 | 33101 | Miami | NULL | NULL | NULL | NULL | NULL |
| 1002 | Dave | Dunkin | Power Street 33a | 10010 | New York | Marry | Dunkin | Power Street 14 | 14205 | Buffalo |
如果你的业务场景中存在一个订单多个收货地址的情况,这个SQL会返回多条记录,到时候你可能需要结合GROUP BY和GROUP_CONCAT来把多个收货地址合并到一个字段里,但根据你给出的需求示例,目前的SQL完全适用。
备注:内容来源于stack exchange,提问作者Kuba
相关产品推荐
相关产品推荐

