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

Oracle左连接返回记录数超左表,两次连接去重方案咨询

Oracle两次关联去重解决方案

问题分析

原逻辑是先筛选出table1中无法通过postcode匹配table2的记录,再用AL1_POST_TOWN_NAME与table2关联,但table2中同一TOWNNAME对应多条记录,导致结果集膨胀。同时原SQL用MINUS的写法效率较低,可先优化基础查询逻辑。

优化基础查询(替代MINUS)

原SQL的MINUS写法可替换为LEFT JOIN + IS NULL,更高效且能保留table1原有的重复记录:

SELECT x.*
FROM table1 x
LEFT JOIN table2 u ON x.postcode = u.postcodelocator
WHERE u.postcodelocator IS NULL

去重解决方案

1. 直接用DISTINCT去重(仅需保留table1字段时)

如果最终只需要table1的字段,直接在最外层添加DISTINCT即可:

SELECT DISTINCT v.*
FROM (
    SELECT x.*
    FROM table1 x
    LEFT JOIN table2 u ON x.postcode = u.postcodelocator
    WHERE u.postcodelocator IS NULL
) v
LEFT JOIN table2 w ON v.AL1_POST_TOWN_NAME = w.TOWNNAME

2. 用ROW_NUMBER()窗口函数筛选唯一匹配记录

需要保留table2字段,或需指定取哪条匹配记录时,用窗口函数按table1主键分组,给匹配的table2记录排序后取第一条:

SELECT v.*, w.需要的字段 -- 按需添加table2字段
FROM (
    SELECT 
        v.*,
        w.*,
        ROW_NUMBER() OVER (PARTITION BY v.主键字段 ORDER BY w.主键字段) AS rn
    FROM (
        SELECT x.*
        FROM table1 x
        LEFT JOIN table2 u ON x.postcode = u.postcodelocator
        WHERE u.postcodelocator IS NULL
    ) v
    LEFT JOIN table2 w ON v.AL1_POST_TOWN_NAME = w.TOWNNAME
) t
WHERE rn = 1

说明:将主键字段替换为table1和table2的实际主键(如id),ORDER BY子句可根据需求选择排序规则(如取最新记录则按创建时间降序)。

3. 提前对table2按TOWNNAME去重

若table2中同一TOWNNAME的记录冗余,可先对table2聚合去重,再进行关联:

SELECT v.*, w.需要的字段
FROM (
    SELECT x.*
    FROM table1 x
    LEFT JOIN table2 u ON x.postcode = u.postcodelocator
    WHERE u.postcodelocator IS NULL
) v
LEFT JOIN (
    SELECT 
        TOWNNAME,
        MAX(字段1) AS 字段1, -- 用MAX/MIN取唯一值,按需选择
        MIN(字段2) AS 字段2
    FROM table2
    GROUP BY TOWNNAME
) w ON v.AL1_POST_TOWN_NAME = w.TOWNNAME

说明:如果只需TOWNNAME字段,也可用SELECT DISTINCT TOWNNAME FROM table2作为子查询。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 10:55:14