You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Oracle中连接含非唯一值的表:解决EBS系统活跃用户查询的笛卡尔积及主管姓名展示问题

解决EBS活跃用户查询的笛卡尔积与主管姓名展示问题

咱们先拆解你碰到的两个核心问题,一步步来解决:

一、搞定笛卡尔积问题

你遇到的笛卡尔积,根源很明确:EMPDATA_IMPORT表中同一个email_address对应了多行重复数据(比如示例里jdoe@mm.com出现了3次)。直接用这个表和fnd_user关联时,每一条用户数据都会和所有匹配的重复行关联,结果行数自然就爆炸了。

解决思路是先对EMPDATA_IMPORT做去重处理,保留每个邮箱对应的唯一supervisor_id(从你的数据示例看,同一邮箱的主管ID是一致的,假设业务逻辑也是如此)。我们用CTE(公共表表达式)来生成去重后的数据集,这样SQL可读性会更高。

二、实现主管姓名展示

要通过主管ID拿到对应的姓名,只需要把去重后的员工表自连接一次:用当前用户的supervisor_id关联员工表的emp_id,就能直接获取主管的全名了。

改写后的完整SQL

WITH emp_data_unique AS (
    -- 对EMPDATA_IMPORT去重,保留每个邮箱对应的唯一员工/主管数据
    SELECT DISTINCT
        emp_id,
        full_name,
        supervisor_id,
        email_address
    FROM EMPDATA_IMPORT
)
SELECT 
    fu.user_name "User name",
    frt.responsibility_name "Responsibility Name",
    furg.start_date "Start Date",
    furg.end_date "End Date",
    fu.last_logon_date "Last Logon Date",
    fr.responsibility_key "Responsibility key",
    fu.email_address "Email Address",
    fu.description "Description",
    x.supervisor_id "Supervisor ID",
    mgr.full_name "Supervisor Name" -- 新增主管姓名列
FROM 
    fnd_user_resp_groups_direct furg
JOIN fnd_user fu 
    ON furg.user_id = fu.user_id
JOIN applsys.fnd_responsibility_tl frt 
    ON furg.responsibility_id = frt.responsibility_id
JOIN applsys.fnd_responsibility fr 
    ON fr.responsibility_id = frt.responsibility_id
JOIN emp_data_unique x 
    ON fu.email_address = x.email_address
LEFT JOIN emp_data_unique mgr 
    ON x.supervisor_id = mgr.emp_id -- 自连接获取主管姓名
WHERE 
    (fu.END_DATE IS NULL OR fu.END_DATE > sysdate)

额外注意事项

  1. 特殊场景处理:如果你的业务中同一邮箱可能对应不同的主管ID(比如存在历史变更记录),可以改用ROW_NUMBER()函数取最新的记录,示例如下:
    WITH emp_data_unique AS (
        SELECT 
            emp_id,
            full_name,
            supervisor_id,
            email_address,
            ROW_NUMBER() OVER (PARTITION BY email_address ORDER BY emp_id DESC) rn
        FROM EMPDATA_IMPORT
        WHERE rn = 1 -- 取每个邮箱对应的最新记录,排序规则可根据实际调整
    )
    
  2. 避免数据丢失:用LEFT JOIN关联主管数据,而不是INNER JOIN,这样即使存在顶级主管(无上级ID),也不会导致该用户的记录被过滤掉。
  3. 语法优化:把原来的隐式连接改成显式JOIN语法,SQL结构更清晰,后续排查关联问题也更方便。

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

火山引擎 最新活动