You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;

代码解释

  1. 用LEFT JOIN而不是INNER JOIN是为了确保即使某个订单只有账单地址(比如你的订单1001),也能正常显示,收货地址字段会以NULL填充
  2. 给两次连接的地址表分别起别名billing_addr和shipping_addr,方便区分不同类型的地址
  3. 对收货地址的字段添加ship_前缀,和账单地址字段做区分

测试结果

用你提供的示例数据运行这个SQL,就能得到你想要的输出:

order_numberfirst_namelast_namestreetzipcodecityship_first_nameship_last_nameship_streetship_zipcodeship_city
1001JohnDoeWashington Street 233101MiamiNULLNULLNULLNULLNULL
1002DaveDunkinPower Street 33a10010New YorkMarryDunkinPower Street 1414205Buffalo

如果你的业务场景中存在一个订单多个收货地址的情况,这个SQL会返回多条记录,到时候你可能需要结合GROUP BY和GROUP_CONCAT来把多个收货地址合并到一个字段里,但根据你给出的需求示例,目前的SQL完全适用。

备注:内容来源于stack exchange,提问作者Kuba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 15:00:27