【问题标题】:Full join in two columns with repeated values完全连接具有重复值的两列
【发布时间】:2023-03-20 15:10:01
【问题描述】:

我有两个如下所示的表:

sMinMax:

PartNo  baseID  Min   Max  
11795   1       1     1
11795   5       0     0
11795   6       1     1
01655   65      2     3 

vs 股票:

PartNo  baseID  Qty
11795   1       1
11795   1       1
11795   55      1

我想加入他们,所以我得到一个表格,其中显示了所有 parNo en 基数的所有列,如下所示:

结果:

PartNo  baseID  Min   Max  Qty
11795   1       1     1     2
11795   5       0     0     null
11795   6       1     1     null
11795   55      null  null  1
01655   65      2     3     null

所以我会在两列上使用完全外连接来执行此操作,但这会产生与左连接所期望的结果相同的结果。我尝试了 1000 次,但这是我最后一次尝试:

SELECT 
 a.sPart_ID
,a.uRALBase_ID
,a.MinQty
,a.MaxQty
,b.Qty

FROM [RALNHVTST].[dbo].[sMinMax] as a

FULL OUTER JOIN [RALNHVTST].[dbo].[vsStockList] as b

ON a.sPart_ID = b.sPart_ID
AND a.uRALBase_ID = b.uRALBase_ID
WHERE a.sPart_ID IS NOT NULL
AND a.sPart_ID = 1159

ORDER BY a.sPart_ID

但正如我所说,这给了我与 LEFT JOIN 相同的结果。有人知道我做错了什么吗?

【问题讨论】:

  • WHERE子句条件使得FULL OUTER JOIN返回LEFT OUTER JOIN结果。

标签: sql tsql join where-clause outer-join


【解决方案1】:

full join 中过滤很棘手。我建议在子查询中过滤和聚合:

SELECT COALESCE(sm.sPart_ID, s.sPart_Id) as sPartId,
       COALESCE(sm.uRALBase_ID, sm.uRALBase_ID
       sm.MinQty, sm.MaxQty, s.Qty
FROM (SELECT sm.*
      FROM [RALNHVTST].[dbo].[sMinMax] sm
      WHERE sm.sPart_ID = 1159
     ) sm FULL OUTER JOIN 
     (SELECT s.sPart_ID, s.uRALBase_ID, SUM(qty) as qty
      FROM [RALNHVTST].[dbo].[vsStockList] s
      WHERE s.sPart_ID = 1159
      GROUP BY s.sPart_ID, s.uRALBase_ID
     ) s
     ON sm.sPart_ID = s.sPart_ID AND
        sm.uRALBase_ID = s.uRALBase_ID
ORDER BY sPart_ID

【讨论】:

    【解决方案2】:

    类似的东西?此查询给出的结果与您预期的相同。

    SELECT 
     CASE WHEN a.PartNo IS NOT NULL THEN a.PartNo ELSE b.PartNo END AS PartNo
    ,CASE WHEN a.baseId IS NOT NULL THEN a.baseId ELSE b.baseId END AS baseId
    ,a.[Min]
    ,a.[Max]
    ,SUM(b.Qty) AS Qty
    
    FROM [dbo].[sMinMax] as a
    
    FULL JOIN [dbo].[vsStock] as b
    
    ON a.partNo = b.partNo
    AND a.baseId = b.baseId
    GROUP BY 
        CASE WHEN a.PartNo IS NOT NULL THEN a.PartNo ELSE b.PartNo END, 
        CASE WHEN a.baseId IS NOT NULL THEN a.baseId ELSE b.baseId END, 
        a.[Min],
        a.[Max]
    ORDER BY 
    CASE WHEN a.PartNo IS NOT NULL THEN a.PartNo ELSE b.PartNo END
    

    【讨论】:

    • 小后续问题:如果我想添加一个 LEFT JOIN 来添加零件的描述,代码会是什么样子?像这样: LEFT JOIN [dbo].[sPart] as c on a.PartNo = c.ID
    • 我会在两个比较之间使用 OR 表达式。像 JOIN [dbo].[sPart] AS c ON c.Id = a.PartNo OR c.Id = b.PartNo 之类的东西。如果您对我的回答满意,请将其标记为正确的解决方案。
    • @CathalClavie 。 . .这没有在您的问题中实现过滤,所以我看不出它有多“完美”。
    • @GordonLinoff 。 . .老实说,我并没有从问题中检查查询,我只是查看了源数据和预期结果。但是在我的解决方案中实现一些 WHERE 条件并不难,例如 WHERE CASE WHEN a.baseId IS NOT NULL THEN a.baseId ELSE b.baseId END = 1159。
    • @OndřejCrha 。 . .过滤full joins 具有挑战性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-01
    • 1970-01-01
    • 2018-05-30
    • 1970-01-01
    • 2017-06-10
    • 2018-12-15
    • 2022-01-02
    相关资源
    最近更新 更多