如何在现有多条件WHERE子句中集成TYPE4、TYPE5筛选逻辑?
整合TYPE4、TYPE5筛选逻辑到现有查询的解决方案
没问题,我帮你把TYPE4和TYPE5的筛选逻辑整合到现有查询里。先理清楚咱们的核心需求:
- TYPE4:用户角色必须是
PRIMARY,且不存在于Table2中满足b.id = a.id AND b.type_id = :P2_TEST_TYPE AND b.status = 'NEW'的记录 - TYPE5:用户角色必须是
SECONDARY,且不存在于Table2中满足上述相同条件的记录
我给你两种实现方案,你可以根据可读性和维护需求选择:
方案一:分支清晰的OR结构
这种写法把每个类型的逻辑拆成独立分支,非常直观,后续修改单个类型的条件也很方便:
SELECT a.ID, a.NAME FROM Table1 a WHERE -- 原有TYPE1、TYPE2逻辑 ( mypackage.get_type_id(TO_NUMBER(:P2_TEST_TYPE)) IN ('TYPE1', 'TYPE2') AND NOT EXISTS ( SELECT 1 FROM Table2 b WHERE b.id = a.id AND b.type_id = :P2_TEST_TYPE AND mypackage.get_category_id(b.parent_id) <> mypackage.get_category_id(:P2_PARENT_ID) AND b.status = 'NEW' ) ) -- 原有TYPE3逻辑 OR ( mypackage.get_type_id(TO_NUMBER(:P2_TEST_TYPE)) = 'TYPE3' AND NOT EXISTS ( SELECT 1 FROM Table2 b WHERE b.id = a.id AND b.type_id = :P2_TEST_TYPE AND b.status = 'NEW' ) ) -- 新增TYPE4逻辑 OR ( mypackage.get_type_id(TO_NUMBER(:P2_TEST_TYPE)) = 'TYPE4' AND mypackage.get_role(a.id) = 'PRIMARY' AND NOT EXISTS ( SELECT 1 FROM Table2 b WHERE b.id = a.id AND b.type_id = :P2_TEST_TYPE AND b.status = 'NEW' ) ) -- 新增TYPE5逻辑 OR ( mypackage.get_type_id(TO_NUMBER(:P2_TEST_TYPE)) = 'TYPE5' AND mypackage.get_role(a.id) = 'SECONDARY' AND NOT EXISTS ( SELECT 1 FROM Table2 b WHERE b.id = a.id AND b.type_id = :P2_TEST_TYPE AND b.status = 'NEW' ) );
改动说明:
- 把原有查询中嵌套在
NOT EXISTS里的类型判断移到了外层分支,避免子查询里重复判断,稍微提升性能 - 为TYPE4和TYPE5新增独立分支,同时包含角色匹配条件和Table2排除条件
- 每个分支的逻辑完全独立,可读性拉满,后续新增类型也能直接复制分支修改
方案二:合并重复逻辑的紧凑结构
如果想减少代码重复,把公共的NOT EXISTS逻辑合并,这种写法更简洁:
SELECT a.ID, a.NAME FROM Table1 a WHERE -- 通用的Table2排除逻辑:根据类型自动适配额外条件 NOT EXISTS ( SELECT 1 FROM Table2 b WHERE b.id = a.id AND b.type_id = :P2_TEST_TYPE AND b.status = 'NEW' -- 仅TYPE1/TYPE2需要额外判断category_id AND ( mypackage.get_type_id(TO_NUMBER(:P2_TEST_TYPE)) NOT IN ('TYPE1', 'TYPE2') OR mypackage.get_category_id(b.parent_id) <> mypackage.get_category_id(:P2_PARENT_ID) ) ) -- 角色判断:仅TYPE4/TYPE5需要验证角色,其他类型直接通过 AND ( mypackage.get_type_id(TO_NUMBER(:P2_TEST_TYPE)) NOT IN ('TYPE4', 'TYPE5') OR (mypackage.get_type_id(TO_NUMBER(:P2_TEST_TYPE)) = 'TYPE4' AND mypackage.get_role(a.id) = 'PRIMARY') OR (mypackage.get_type_id(TO_NUMBER(:P2_TEST_TYPE)) = 'TYPE5' AND mypackage.get_role(a.id) = 'SECONDARY') );
改动说明:
- 把所有类型的
NOT EXISTS逻辑合并成一个子查询,通过内部的OR判断来适配TYPE1/TYPE2的额外category_id条件 - 外层单独处理角色判断:非TYPE4/TYPE5的类型直接跳过角色验证,只有这两个类型需要匹配对应角色
- 代码更紧凑,重复代码最少,适合后续类型较多的场景
内容的提问来源于stack exchange,提问作者Coding Duchess
相关产品推荐
相关产品推荐

