通过检查其他行中的值从 JOIN table 获取结果

Get result from JOIN table by checking values in other rows

我在人和订单之间有 1..n 关系。 订单可以具有活动或取消状态。 一个人最多可以拥有一个 ACTIVE 订单,但可以拥有无​​限数量的 CANCELED 订单。 让我们假设我加入 table 的内容如下所示:

为了获得活跃订单的人,我的查询只是:

select * from persons p inner join orders o on p.id = o.person_id where o.status = 'ACTIVE';

结果应该是id为1和3的人,很简单。

但是现在,我需要获取所有没有任何 ACTIVE shipping 的人,因此此类查询的结果应该是 id 为 2 的人(不一定必须是不同的行)。我不能在上面的查询中只更改为 != 'ACTIVE',因为这样我就得到了所有这 3 个人,因为他们都有状态不是 ACTIVE 的订单。

如果我要用文字来解释它,我会说对于每一行,我还需要检查具有相同 p.id 的其他行,并检查它们中是否没有出现 ACTIVE 状态。

有什么建议可以实现吗?

I need to get all those persons which don't have any ACTIVE shipping

您可以使用 not exists:

select * 
from persons p 
where not exists (
    select 1 
    from orders o
    where o.person_id = p.id and o.status = 'ACTIVE'
);

为了提高此查询的性能,请考虑 orders(person_id, status).

上的索引

请注意,这也允许完全没有订单的人。如果您想避免这种情况,请改用聚合:

select p.* 
from persons p 
inner join orders o on o.person_id = p.id
group by p.id
having max(o.status = 'ACTIVE') = 0

您可以使用聚合:

select p.*
from persons p inner join
     orders o
     on p.id = o.person_id
group by p.id
having sum(o.status = 'ACTIVE') = 0;