Oracle SQL:如何关联存在的数据并保留全部基础查询记录?
解决Oracle SQL中保留基础记录并关联符合条件字段的问题
我明白你的需求了——要保留基础查询的30条员工记录,同时只展示那些在ONBOARDING_STATUS表中存在且符合DESCRIPTION LIKE 'START'、CANCELLED IS NULL条件的关联字段,还要避免重复记录。下面给你两个可行的方案:
方案1:使用LEFT JOIN + 条件过滤 + DISTINCT
核心思路是用LEFT JOIN替代内联(JOIN),这样不会过滤掉没有匹配关联记录的员工;同时在SELECT的CASE语句里只返回符合条件的字段值,最后用DISTINCT去重(如果存在一个员工多条符合条件的关联记录时,这个方法能合并重复的基础记录)。
SELECT DISTINCT E.EMPLOYEE_NUM "Employee #", D.START_DATE "Start Date", E.NAME "Employee Name", CASE WHEN OS.DESCRIPTION LIKE 'START' AND OS.CANCELLED IS NULL THEN OS.ONBOARDING_LOCATION ELSE NULL END "On-boarding Location", CASE WHEN OS.DESCRIPTION LIKE 'START' AND OS.CANCELLED IS NULL THEN OS.COMPLETION_DATE ELSE NULL END "Completion Date" FROM EMPLOYEES E JOIN EMPLOYEE_DETAILS D ON D.EMPLOYEE_ID = E.EMPLOYEE_ID LEFT JOIN ONBOARDING_STATUS OS ON OS.EMPLOYEE_ID = E.EMPLOYEE_ID WHERE D.START_DATE >= DATE '2016-12-14' ORDER BY 1;
方案2:使用LEFT JOIN + 聚合函数(更稳妥的去重方式)
如果某个员工在ONBOARDING_STATUS表中有多条符合条件的记录,DISTINCT可能还是会产生重复行(比如不同的ONBOARDING_LOCATION或COMPLETION_DATE)。这时可以用聚合函数(比如MAX、MIN)来获取唯一的关联值,确保每条基础记录只出现一次:
SELECT E.EMPLOYEE_NUM "Employee #", D.START_DATE "Start Date", E.NAME "Employee Name", MAX(CASE WHEN OS.DESCRIPTION LIKE 'START' AND OS.CANCELLED IS NULL THEN OS.ONBOARDING_LOCATION ELSE NULL END) "On-boarding Location", MAX(CASE WHEN OS.DESCRIPTION LIKE 'START' AND OS.CANCELLED IS NULL THEN OS.COMPLETION_DATE ELSE NULL END) "Completion Date" FROM EMPLOYEES E JOIN EMPLOYEE_DETAILS D ON D.EMPLOYEE_ID = E.EMPLOYEE_ID LEFT JOIN ONBOARDING_STATUS OS ON OS.EMPLOYEE_ID = E.EMPLOYEE_ID WHERE D.START_DATE >= DATE '2016-12-14' GROUP BY E.EMPLOYEE_NUM, D.START_DATE, E.NAME ORDER BY 1;
关键知识点解释:
- LEFT JOIN:确保基础查询的所有30条记录都被保留,即使没有匹配的
ONBOARDING_STATUS数据,关联字段会显示为NULL。 - CASE语句:只在关联记录符合条件时返回对应字段值,否则返回
NULL,避免展示不符合条件的关联数据。 - 聚合函数+GROUP BY:彻底解决重复问题,通过分组基础记录的唯一标识(员工编号、入职日期、姓名),用聚合函数提取唯一的关联字段值(如果有多个符合条件的记录,这里用
MAX取最大/最新的,你可以根据需求换成MIN)。
内容的提问来源于stack exchange,提问作者grigs
相关产品推荐
相关产品推荐

