简体   繁体   English

父表中的 Select 记录取决于子表中的条件

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM