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

SQL关联box与container表按两列排序获取去重结果的实现问题

解决方案

你遇到数据翻倍的核心原因是:相同关联维度下,#box有2个不重复BoxId,#container有2个不重复ContainerId,直接关联后会产生笛卡尔积2*2=4条结果。你需要的是同维度下两个表的唯一ID按固定排序一一配对,实现方式如下:

-- 先分别对两个表按维度分组,获取去重后的ID列表并按ID排序生成稳定行号
WITH DistinctBox AS (
    SELECT DISTINCT OrderId, BoxId, width, height, weight
    FROM #box
),
BoxRanked AS (
    SELECT *, 
        ROW_NUMBER() OVER(PARTITION BY OrderId, width, height, weight ORDER BY BoxId ASC) AS rn
    FROM DistinctBox
),
DistinctContainer AS (
    SELECT DISTINCT OrderId, ContainerId, width, height, weight
    FROM #container
),
ContainerRanked AS (
    SELECT *, 
        ROW_NUMBER() OVER(PARTITION BY OrderId, width, height, weight ORDER BY ContainerId ASC) AS rn
    FROM DistinctContainer
)
SELECT b.OrderId, c.ContainerId, b.BoxId, b.width, b.height, b.weight
FROM BoxRanked b
INNER JOIN ContainerRanked c 
    ON b.OrderId = c.OrderId
    AND b.width = c.width
    AND b.height = c.height
    AND b.weight = c.weight
    AND b.rn = c.rn
ORDER BY c.ContainerId, b.BoxId

方案说明

  • 首先通过DISTINCT分别清洗两个表的重复行,确保每个ID+维度组合只保留1条
  • 生成行号时指定按主键ID本身排序,因为ID是唯一值,所以行号生成规则完全稳定,不存在匹配不稳定的问题
  • 最终关联时加上行号匹配条件,同维度下第N个Box匹配第N个Container,即可得到你要的2条结果

如果你确实完全不想用ROW_NUMBER,也可以用聚合匹配的方式实现,适合两个表同维度下ID数量完全对等的场景:

WITH BoxAgg AS (
    SELECT OrderId, width, height, weight,
        STRING_AGG(BoxId, ',') WITHIN GROUP (ORDER BY BoxId) AS BoxIds
    FROM (SELECT DISTINCT OrderId, BoxId, width, height, weight FROM #box) t
    GROUP BY OrderId, width, height, weight
),
ContainerAgg AS (
    SELECT OrderId, width, height, weight,
        STRING_AGG(ContainerId, ',') WITHIN GROUP (ORDER BY ContainerId) AS ContainerIds
    FROM (SELECT DISTINCT OrderId, ContainerId, width, height, weight FROM #container) t
    GROUP BY OrderId, width, height, weight
)
SELECT b.OrderId, 
    CAST(value AS INT) AS BoxId,
    CAST(JSON_VALUE('["' + REPLACE(ContainerIds, ',', '","') + '"]', CONCAT('$[', [key], ']')) AS INT) AS ContainerId,
    b.width, b.height, b.weight
FROM BoxAgg b
INNER JOIN ContainerAgg c 
    ON b.OrderId = c.OrderId AND b.width = c.width AND b.height = c.height AND b.weight = c.weight
CROSS APPLY OPENJSON('["' + REPLACE(BoxIds, ',', '","') + '"]')
ORDER BY ContainerId, BoxId

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 10:24:04