如何在Oracle SQL中实现同表内多员工层级的多对多匹配
问题描述
我有一张存储员工信息的表,包含完整的员工层级结构,员工可处于层级中的任意级别。查询特定员工的相关属性时,以下WHERE子句可以正常运行:
WHERE 'myEmployee@mycompany.com' IN ANY(manager_3, manager_4, manager_5, manager_6, employee_email)
但需要处理多名员工(可能是管理者也可能不是)时遇到了问题:我无法修改表结构,需要查询出1名或多名员工所在层级链中的所有人员。比如有3名员工,不清楚他们的层级级别,要找出所有向这3人汇报的人员。我尝试了类似以下的SQL,但无法生效:
SELECT employee_email FROM myTable WHERE ('Emp1@company.com', 'Emp2@company.com', 'Emp3@company.com') = ANY(manager_3, manager_4, manager_5, manager_6, employee_email)
有没有比写3个独立ANY子句更简洁高效的写法?
解决方案
可以通过子查询+字符串拆分的方式实现,把目标员工的邮箱列表转成数据集后,再和原表做关联匹配,不用重复写多个ANY子句。
字符串拆分实现
先把逗号分隔的员工邮箱字符串拆成单独的行:
WITH Q_STR AS (SELECT 'Emp1@company.com,Emp2@company.com,Emp3@company.com' STR FROM DUAL) SELECT TRIM(COLUMN_VALUE) AS target_email FROM Q_STR, XMLTABLE(('"' || REPLACE(STR, ',', '","') || '"'));
关联原表查询
把上面的拆分结果作为子查询,和原表关联,判断原表的层级字段中是否存在匹配的目标邮箱:
SELECT t.employee_email FROM myTable t JOIN ( WITH Q_STR AS (SELECT 'Emp1@company.com,Emp2@company.com,Emp3@company.com' STR FROM DUAL) SELECT TRIM(COLUMN_VALUE) AS target_email FROM Q_STR, XMLTABLE(('"' || REPLACE(STR, ',', '","') || '"')) ) target ON target.target_email IN (t.manager_3, t.manager_4, t.manager_5, t.manager_6, t.employee_email);
这种写法只需要维护逗号分隔的目标员工字符串即可,既简洁又高效,也不用修改原有表结构。
内容的提问来源于stack exchange,提问作者user1009073
相关产品推荐
相关产品推荐

