[英]Select records from parent table depending on a condition in child table
I have two tables: Order (parent) and Expedient (child)我有两个表:订单(父)和权宜之计(子)
Suppose this case:假设这种情况:
Order
id |
order1 |
Expedient
id | order_id | status
1 | order1 | validated
2 | order1 | validated
3 | order1 | validated
4 | order1 | pending
I need a query that returns Order but only when the 4 child records are in state "validated"我需要一个返回订单的查询,但仅当 4 个子记录在 state “已验证”时
If at least one of the records is in pending status, then no Order should be returned如果至少有一条记录处于待处理状态,则不应返回任何订单
I have tried with a subquery "NOT IN" excluding all pending expedients, but it's not working because always return me a Order我尝试使用子查询“NOT IN”排除所有待处理的权宜之计,但它不起作用,因为总是给我返回一个订单
You could try using having count(status) >= 4您可以尝试使用让 count(status) >= 4
select o.order_id
from `Order` o
INNER JOIN Expedient e ON o.order_id = e.order_id
WHERE e.status = 'validated'
GROUP BY o.order_id
having count(e.status) >= 4
be careful using order as table name you need backtics..and should be better use another name.小心使用 order 作为表名,您需要 backtics ..并且应该更好地使用另一个名称。
and if you need also pendind = 0 then the having clause is如果您还需要pendind = 0,那么having子句是
having count(e.status) >= 4 AND sum(status ='pending' ) =0
If all you need is the order's id then there is no need for a join:如果您只需要订单的 ID,则无需加入:
select order_id
from Expedient
group by order_id
having sum(status = 'pending') = 0
I assume there are only the values 'validated'
and 'pending'
in the column status
.我假设列
status
中只有值'validated'
和'pending'
。
If you want exactly 4 rows with the value 'validated'
in status
:如果您想要 4 行的
status
值为'validated'
:
select order_id
from Expedient
group by order_id
having sum(status = 'pending') = 0 and sum(status = 'validated') = 4
If at least one of the records is in pending status, then no Order should be returned
如果至少有一条记录处于待处理状态,则不应返回任何订单
This is a case for a NOT EXISTS
subquery:这是
NOT EXISTS
子查询的情况:
select o.*
from `Order` o
where not exists (
select *
from Expedient e
where e.order_id = o.id
and e.status = 'pending'
)
An equivalent method is an "anti-join":等效的方法是“反连接”:
select o.*
from `Order` o
left join Expedient e
on e.order_id = o.id
and e.status = 'pending'
where e.order_id is null
For both queries you should have an andex on Expedient(order_id, status [, other columns])
or Expedient(status, order_id, [, other columns])
.对于这两个查询,您应该在
Expedient(order_id, status [, other columns])
或Expedient(status, order_id, [, other columns])
上有一个 andex。
A NOT IN
query might also work: NOT IN
查询也可能有效:
select o.*
from `Order` o
where o.id not in (
select e.order_id
from Expedient e
where e.status = 'pending'
)
But note, that it might return nothing, if Expedient.order_id
can be NULL
.但请注意,如果
Expedient.order_id
可以是NULL
,它可能不会返回任何内容。 For this query you should have an index on Expedient(status [, other columns])
- Ideally Expedient(status, order_id, [, other columns])
.对于此查询,您应该在
Expedient(status [, other columns])
上有一个索引 - 理想情况下Expedient(status, order_id, [, other columns])
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.