过滤子记录时如何使用不存在子句

how to use not exists clause while filtering child records

我有 Order 和 OrderSubscription tables.the 表之间的关系是一个 many.I 我正在使用 oracle 11g。 我想找出那些所有 OrderSubscriptions 都应该过期但应该有有效订单的订单。

所以最终结果应该是 order id =1 and order id =4 记录..

试过下面query.Or还有其他方法可以过滤记录吗?

select * from order ord where
ord.order_status='Active'
and not exists(select 'x' from OrderSubscription os where ord.id=os.order_id and subs_status='Expired')

************************************************************************************

insert into Order(id,order_numbr,order_status) (1,12345,'Active')   

insert into OrderSubscription(id,order_id,subs_name,subs_status) (1,1,'360 fhf','Expired')   
insert into OrderSubscription(id,order_id,subs_name,subs_status) (2,1,'720 cef','Expired') 



insert into Order(id,order_numbr,order_status) (2,5757575,'Active')   

insert into OrderSubscription(id,order_id,subs_name,subs_status) (1,2,'360 fhf','Active')   
insert into OrderSubscription(id,order_id,subs_name,subs_status) (2,2,'720 cef','Expired') 
insert into OrderSubscription(id,order_id,subs_name,subs_status) (3,2,'540 abc','Expired') 


insert into Order(id,order_numbr,order_status) (3,979797979,'Active')   

insert into OrderSubscription(id,order_id,subs_name,subs_status) (1,3,'360 fhf','Expired')   
insert into OrderSubscription(id,order_id,subs_name,subs_status) (2,3,'720 cef','Expired') 
insert into OrderSubscription(id,order_id,subs_name,subs_status) (3,3,'120 juh','Pending') 
insert into OrderSubscription(id,order_id,subs_name,subs_status) (4,3,'60 ert','Active')


insert into Order(id,order_numbr,order_status) (4,3131313133,'Active')   

insert into OrderSubscription(id,order_id,subs_name,subs_status) (1,4,'360 fhf','Expired')   

这可能是一种选择:检查唯一状态是否为“已过期”并仅获取那些订单 ID(如果它们为“有效”)。

SQL> with os as
  2    (select order_id, min(subs_status) minstatus, max(subs_status) maxstatus
  3     from ordersubscription
  4     group by order_id
  5    )
  6  select t.id
  7  from torder t join os o on o.order_id = t.id
  8  where t.order_status = 'Active'
  9    and o.minstatus = o.maxstatus
 10    and o.minstatus = 'Expired';

        ID
----------
         1
         4

SQL>

您可以在子查询中使用 EXISTSHAVING 子句进行聚合比较,以检查是否所有 Expired 状态的计数以及每组 order_id 值:

SELECT *
  FROM orders o
 WHERE o.order_status = 'Active'
   AND EXISTS (SELECT 1
                 FROM OrderSubscription os
                WHERE os.order_id = o.id
                GROUP BY os.order_id
               HAVING SUM(CASE WHEN os.subs_status = 'Expired' THEN 1 ELSE 0 END)
                    = COUNT(os.id))

其中 table 名称 order 替换为 orders,因为 order 是保留关键字。

Demo

根据您的问题,您需要的查询是:

select ord.*
from order ord
where ord.order_status = 'Active' and
      not exists (select 'x'
                  from OrderSubscription os
                  where ord.id = os.order_id and
                        subs_status = 'Active'
                 );

有了 OrderSubscription(order_id, subs_status) 上的索引,这可能是所有替代逻辑公式中性能最好的。