首页 > 解决方案 > 通过检查其他行中的值从 JOIN 表中获取结果

问题描述

我在人和订单之间有 1..n 关系。订单可以有 ACTIVE 或 CANCELED 状态。一个人最多可以有一个 ACTIVE 订单,但可以有无限数量的 CANCELED 订单。让我们假设我的联接表的内容如下所示:

在此处输入图像描述

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

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

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

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

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

有什么建议我怎样才能做到这一点?

标签: mysqlsqljoinsubqueryinner-join

解决方案


我需要让所有没有任何 ACTIVE 运输的人

您可以使用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

推荐阅读