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

两临时表全外连接:前5列匹配后两列非空不匹配时保留B表记录

解决SQL全外连接保留特定不匹配行的问题

要对两个临时表做全外连接,核心需求就是:当A表和B表的前5列(RowID/B_RowID、fr_billto/B_fr_billto、ord_revtype2/B_ord_revtype2、stp_mileagetype/B_stp_mileagetype、stp_type1/B_stp_type1)匹配时,哪怕后两列(A.BasisUnit与B.B_TARBasisUnit、A.RateUnit与B.B_RateUnit)非空且不匹配,也得保留B表中对应的行。之前的连接条件因为把后两列的严格匹配也加进去了,导致这类B表记录直接被过滤掉了。

解决方案一:调整连接键+WHERE筛选

把连接条件只限定在前5列,再通过WHERE子句筛选出所有需要保留的场景:

SELECT 
    A.RowID,
    A.fr_billto,
    A.ord_revtype2,
    A.stp_mileagetype,
    A.stp_type1,
    A.BasisUnit,
    A.RateUnit,
    B.B_RowID,
    B.B_fr_billto,
    B.B_ord_revtype2,
    B.B_stp_mileagetype,
    B.B_stp_type1,
    B.B_TARBasisUnit,
    B.B_RateUnit,
    B.B_TARCode
FROM 
    #TempA A
FULL OUTER JOIN 
    #TempB B ON 
        A.RowID = B.B_RowID 
        AND A.fr_billto = B.B_fr_billto 
        AND A.ord_revtype2 = B.B_ord_revtype2 
        AND A.stp_mileagetype = B.B_stp_mileagetype 
        AND A.stp_type1 = B.B_stp_type1
WHERE 
    -- 保留前后列都匹配的原有效行
    (A.BasisUnit = B.B_TARBasisUnit AND A.RateUnit = B.B_RateUnit)
    -- 保留前5列匹配、后两列非空但不匹配的B表行
    OR (A.RowID IS NOT NULL 
        AND B.B_TARBasisUnit IS NOT NULL 
        AND B.B_RateUnit IS NOT NULL 
        AND NOT (A.BasisUnit = B.B_TARBasisUnit AND A.RateUnit = B.B_RateUnit))
    -- 保留A表独有的行
    OR B.B_RowID IS NULL
    -- 保留B表完全无A表匹配的行
    OR A.RowID IS NULL;

解决方案二:UNION ALL拆分场景

把需求拆成三个独立的查询,用UNION ALL合并结果,逻辑更直观:

-- 1. A表所有行 + 后两列匹配的B表对应行
SELECT 
    A.*, B.*
FROM #TempA A
LEFT JOIN #TempB B ON 
    A.RowID = B.B_RowID 
    AND A.fr_billto = B.B_fr_billto 
    AND A.ord_revtype2 = B.B_ord_revtype2 
    AND A.stp_mileagetype = B.B_stp_mileagetype 
    AND A.stp_type1 = B.B_stp_type1
    AND A.BasisUnit = B.B_TARBasisUnit 
    AND A.RateUnit = B.B_RateUnit

UNION ALL

-- 2. 前5列匹配、后两列非空但不匹配的B表行
SELECT 
    A.*, B.*
FROM #TempA A
JOIN #TempB B ON 
    A.RowID = B.B_RowID 
    AND A.fr_billto = B.B_fr_billto 
    AND A.ord_revtype2 = B.B_ord_revtype2 
    AND A.stp_mileagetype = B.B_stp_mileagetype 
    AND A.stp_type1 = B.B_stp_type1
WHERE 
    B.B_TARBasisUnit IS NOT NULL 
    AND B.B_RateUnit IS NOT NULL 
    AND NOT (A.BasisUnit = B.B_TARBasisUnit AND A.RateUnit = B.B_RateUnit)

UNION ALL

-- 3. B表中没有A表前5列匹配的行
SELECT 
    A.*, B.*
FROM #TempA A
RIGHT JOIN #TempB B ON 
    A.RowID = B.B_RowID 
    AND A.fr_billto = B.B_fr_billto 
    AND A.ord_revtype2 = B.B_ord_revtype2 
    AND A.stp_mileagetype = B.B_stp_mileagetype 
    AND A.stp_type1 = B.B_stp_type1
WHERE A.RowID IS NULL;

两种方案都能满足需求,第一种适合追求简洁的场景,第二种拆分后逻辑更清晰,便于后续维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 21:00:40