我有一个带有条件WHERE子句的查询,其中我根据页面项从Table1中选择用户。
如果某个页面项的值为TYPE1或TYPE2,我从Table1中选择不在Table2中的用户,并满足第一个条件, 并且如果用户属于TYPE3,则在第二种情况下,我将从Table2中选择不在Table2中的用户。
现在我需要再添加两个类型TYPE4和TYPE5,但是困难在于,如果用户使用这两种类型中的任何一种,
在带有status='NEW'
SELECT 1
FROM Table2 b
WHERE b.id = a.id
AND b.type_id = :P2_TEST_TYPE
AND b.status = 'NEW'`
但应分别扮演“ PRIMARY”和“ SECONDARY”角色:
mypackage.get_role(a.id) = 'PRIMARY' AND mypackage.get_type_id(TO_NUMBER(:P2_TEST_TYPE))='TYPE4'
AND
mypackage.get_role(a.id) = 'SECONDARY' AND mypackage.get_type_id(TO_NUMBER(:P2_TEST_TYPE))='TYPE5'
下面处理TYPE1,TYPE2和TYPE3的查询。如何将TYPE4和TYPE5的条件纳入此查询:
SELECT a.ID, a.NAME
FROM Table1 a
WHERE 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'
AND mypackage.get_type_id(TO_NUMBER(:P2_TEST_TYPE)) IN ('TYPE1', 'TYPE2')
UNION ALL
SELECT 1
FROM Table2 b
WHERE b.id = a.id
AND b.type_id = :P2_TEST_TYPE
AND b.status = 'NEW'
AND mypackage.get_type_id(TO_NUMBER(:P2_TEST_TYPE)) = 'TYPE3'
);
答案 0 :(得分:0)
由于两个子查询都非常相似,因此建议您将所有常见的AND
条件提取到一个子查询中,并为每个替代条件添加一个额外的OR
。然后,将每组条件按它们的公共子条件(与b.status
有关的子条件)分组:
SELECT a.ID, a.NAME
FROM Table1 a
WHERE NOT EXISTS
(
SELECT 1
FROM Table2 b
WHERE b.id = a.id
AND b.type_id = :P2_TEST_TYPE
AND
(
(
b.status = 'NEW' AND
(
(
mypackage.get_type_id(TO_NUMBER(:P2_TEST_TYPE)) IN ('TYPE1', 'TYPE2')
AND
mypackage.get_category_id(b.parent_id) <> mypackage.get_category_id(:P2_PARENT_ID)
)
OR (mypackage.get_type_id(TO_NUMBER(:P2_TEST_TYPE)) = 'TYPE3')
)
)
OR
(
b.status <> 'NEW' AND
(
(mypackage.get_role(a.id) = 'PRIMARY' AND mypackage.get_type_id(TO_NUMBER(:P2_TEST_TYPE))='TYPE4')
OR (mypackage.get_role(a.id) = 'SECONDARY' AND mypackage.get_type_id(TO_NUMBER(:P2_TEST_TYPE))='TYPE5')
)
)
)
);
当然,它引发了太多的复杂性。您应该考虑改用客户端语言过程。
答案 1 :(得分:0)
决定在两个区域之间划分逻辑,然后使用show / hide显示适当的区域