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

SQL Server多表关联去重:获取指定格式的合并查询结果

解决SQL Server多表左关联笛卡尔积重复问题

完全可以实现需求,你遇到的重复是因为关联的子表(Tbl_Production、Tbl_Adjusment、Tbl_Assembly)中,同一(ProdCode,Batchno)存在多条记录,左关联后不同子表的记录两两组合产生了笛卡尔积。以下是三种常用解决方案:

方案一:聚合函数分组去重

如果需要将子表中同一批次的多条记录合并为汇总值(如总和、最大值),可以用GROUP BY结合聚合函数实现:

SELECT 
    p.ProdCode,
    p.Batchno,
    -- 按业务需求聚合生产表数据,比如汇总数量
    ISNULL(SUM(prod.Qty), 0) AS TotalProductionQty,
    -- 汇总调整表的调整数量
    ISNULL(SUM(adj.AdjustQty), 0) AS TotalAdjustmentQty,
    -- 取组装表的最新状态(假设有CreateTime字段)
    ISNULL(MAX(asm.AssemblyStatus), '未组装') AS LatestAssemblyStatus
FROM Tbl_Product p
LEFT JOIN Tbl_Production prod 
    ON p.ProdCode = prod.ProdCode AND p.Batchno = prod.Batchno
LEFT JOIN Tbl_Adjusment adj 
    ON p.ProdCode = adj.ProdCode AND p.Batchno = adj.Batchno
LEFT JOIN Tbl_Assembly asm 
    ON p.ProdCode = asm.ProdCode AND p.Batchno = asm.Batchno
GROUP BY p.ProdCode, p.Batchno;

方案二:APPLY关联子查询取单条记录

如果需要从每个子表中提取特定单条记录(比如最新创建的),OUTER APPLY比普通左关联更灵活,能直接避免笛卡尔积:

SELECT 
    p.ProdCode,
    p.Batchno,
    prod.Qty AS LatestProductionQty,
    adj.AdjustQty AS LatestAdjustmentQty,
    asm.AssemblyStatus AS LatestAssemblyStatus
FROM Tbl_Product p
-- 取该批次最新的生产记录
OUTER APPLY (
    SELECT TOP 1 Qty 
    FROM Tbl_Production 
    WHERE ProdCode = p.ProdCode AND Batchno = p.Batchno
    ORDER BY CreateTime DESC -- 替换为实际排序字段,比如操作时间
) prod
-- 取该批次最新的调整记录
OUTER APPLY (
    SELECT TOP 1 AdjustQty 
    FROM Tbl_Adjusment 
    WHERE ProdCode = p.ProdCode AND Batchno = p.Batchno
    ORDER BY CreateTime DESC
) adj
-- 取该批次最新的组装记录
OUTER APPLY (
    SELECT TOP 1 AssemblyStatus 
    FROM Tbl_Assembly 
    WHERE ProdCode = p.ProdCode AND Batchno = p.Batchno
    ORDER BY CreateTime DESC
) asm;

方案三:合并子表多条记录为字符串(SQL Server 2017+)

如果需要把子表中同一批次的多条记录值合并为单个字符串(比如用逗号分隔),可以用STRING_AGG函数:

SELECT 
    p.ProdCode,
    p.Batchno,
    ISNULL(STRING_AGG(prod.Qty, ', '), '') AS ProductionQtyList,
    ISNULL(STRING_AGG(adj.AdjustQty, ', '), '') AS AdjustmentQtyList
FROM Tbl_Product p
LEFT JOIN Tbl_Production prod 
    ON p.ProdCode = prod.ProdCode AND p.Batchno = prod.Batchno
LEFT JOIN Tbl_Adjusment adj 
    ON p.ProdCode = adj.ProdCode AND p.Batchno = adj.Batchno
GROUP BY p.ProdCode, p.Batchno;

关键注意事项

  • 关联时必须同时匹配ProdCode和Batchno两个联合主键字段,避免因关联条件不全导致的笛卡尔积;
  • 根据实际业务需求选择对应方案,比如需要汇总就用聚合,需要单条记录就用APPLY,需要合并字符串就用STRING_AGG。

内容的提问来源于stack exchange,提问作者Bambang Setiawan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 13:15:34