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

多表JOIN查询存在重复行,如何合并为每个客户仅返回单条记录

erd

问题根源

你遇到的重复行是笛卡尔积导致的:同一个客户的M条购买商品记录和N条退货商品记录直接关联时,会生成M*N条数据,也就是你看到的2个购买+2个退货返回4条重复记录的情况。

实现方案

不需要复杂逻辑,只要先在子查询中分别按客户维度聚合所有购买商品、退货商品,再和客户表、省份表关联即可,主流数据库都有内置的字符串拼接聚合函数,用法非常简单:

示例代码

SELECT 
  CUSTOMER.CUSTFNAME || ' ' || CUSTOMER.CUSTLNAME AS "CUSTOMER",
  COALESCE(order_agg.items_purchased, '') AS "ITEMS PURCHASED",
  COALESCE(return_agg.returns, '') AS "RETURNS",
  STATES.STATENAME
FROM CUSTOMER 
INNER JOIN STATES ON CUSTOMER.STATEID = STATES.STATEID
-- 关联预聚合的购买商品数据
LEFT JOIN (
  SELECT 
    ORDER.CUSTID,
    -- 不同数据库替换对应聚合函数即可:
    -- MySQL:GROUP_CONCAT(ORDERITEM.ITEMDESC SEPARATOR ', ')
    -- PostgreSQL / SQL Server:STRING_AGG(ORDERITEM.ITEMDESC, ', ')
    -- Oracle:LISTAGG(ORDERITEM.ITEMDESC, ', ') WITHIN GROUP (ORDER BY ORDERITEM.ITEMDESC)
    STRING_AGG(ORDERITEM.ITEMDESC, ', ') AS items_purchased
  FROM ORDER 
  INNER JOIN ORDERITEM ON ORDER.OITEMID = ORDERITEM.OITEMID
  GROUP BY ORDER.CUSTID
) order_agg ON CUSTOMER.CUSTID = order_agg.CUSTID
-- 关联预聚合的退货商品数据
LEFT JOIN (
  SELECT 
    RETURN.CUSTID,
    -- 同上替换对应数据库聚合函数
    STRING_AGG(RETURNITEM.ITEMDESCS, ', ') AS returns
  FROM RETURN 
  INNER JOIN RETURNITEM ON RETURN.RITEMID = RETURNITEM.RITEMID
  GROUP BY RETURN.CUSTID
) return_agg ON CUSTOMER.CUSTID = return_agg.CUSTID;

注意事项

  • 子查询按客户ID分组后每个客户仅返回1行数据,关联后不会再产生笛卡尔积重复
  • 使用LEFT JOIN是为了兼容没有购买记录/没有退货记录的客户也能正常返回,如果你只需要同时有购买和退货记录的客户,把LEFT JOIN改成INNER JOIN即可
  • ORDER和RETURN都是SQL保留关键字,作为表名使用时建议加引号转义,避免执行报错

内容的提问来源于stack exchange,提问作者Evan Barre

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 13:54:05