在 sql oracle 中有效地找到已删除的位置

find deleted positiones effectively in sql oracle

我有一个巨大的 table,其中有数百万个采购订单。 我也在尝试从性能角度寻找更好的方法来实现目标。

这里是一些示例数据,每个订单都有几个位置,位置0是header,位置1-2是一些商品。在某些情况下,买家下订单时有多个仓位,稍后他可以调整这些仓位,例如删除所有仓位,在这种情况下,所有仓位都会得到 flaf 'y' 和仓位 0(在我们的例子中是 order2六月)。在某些情况下,他不会像我们的简单数据集(6 月的 order1)那样只删除一个。

create table orders (
po varchar2(6),
pos number,
flag char(1),
datum date
)

insert into orders values ('order1',0,'n',to_date('01-01-2020','dd-MM-yyyy'));
insert into orders values ('order1',1,'n',to_date('01-01-2020','dd-MM-yyyy'));
insert into orders values ('order1',2,'n',to_date('01-01-2020','dd-MM-yyyy'));
insert into orders values ('order1',0,'n',to_date('01-06-2020','dd-MM-yyyy'));
insert into orders values ('order1',1,'y',to_date('01-06-2020','dd-MM-yyyy'));
insert into orders values ('order1',2,'n',to_date('01-06-2020','dd-MM-yyyy'));

insert into orders values ('order2',0,'n',to_date('01-01-2020','dd-MM-yyyy'));
insert into orders values ('order2',1,'n',to_date('01-01-2020','dd-MM-yyyy'));
insert into orders values ('order2',2,'n',to_date('01-01-2020','dd-MM-yyyy'));
insert into orders values ('order2',0,'y',to_date('01-06-2020','dd-MM-yyyy'));
insert into orders values ('order2',1,'y',to_date('01-06-2020','dd-MM-yyyy'));
insert into orders values ('order2',2,'y',to_date('01-06-2020','dd-MM-yyyy'));

目标是找到至少有一个已删除位置的订单名称(位置 0 除外,这将通过删除所有位置 1-2 自动设置)

在我们的例子中,结果只是 order1

这个当然不行

select distinct po from orders where pos <> 0 and flag = 'y';

解决方案是子查询或关联子查询

select distinct po from orders
where pos <> 0 and flag = 'y'
and po not in (
select distinct po from orders
where pos = 0 and flag = 'y');

但我想知道从性能的角度是否有更好的解决方案,因为 table 被查询了两次并且有大量的采购订单当然太慢了

有什么想法吗?

使用聚合:

select po
from orders o
group by po
having sum(case when pos = 1 and flag = 'y' then 1 else 0 end) = 0 and
       sum(case when flag = 'y' then 1 else 0 end) > 0;
   

您可能需要条件聚合:

select po
from tab
group by po
having max(case when pos <> 0 then flag end) = 'y' -- at least one deleted position
   and max(case when pos =  0 then flag end) = 'n' -- but no deleted header