通过检查其他行中的值从 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;
我在人和订单之间有 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;