用简单的JOIN苦苦挣扎

时间:2015-06-20 15:26:21

标签: sql postgresql

我觉得我的问题太复杂了。我有一个情况,我有2个表:

orders:
- order_id

order_products:
- order_id
- status

如果每个订单产品都具有独立状态(例如:已发货,延期交货等),我希望能够编写一个查询,说“向我展示其产品全部已发货的所有订单。”

2 个答案:

答案 0 :(得分:2)

这样做的一种方法是查找所有订单,其中不包含除运送状态之外的任何商品。

SELECT * 
  FROM orders o 
 WHERE NOT EXISTS(
         SELECT 1 
           FROM order_products p 
          WHERE o.order_id=p.order_id 
            AND status <> 'shipped'
       )

在SQL Server中,这种NOT EXISTS查询通常比使用连接更有效。我对postgresql不确定。

这当然假设已发货是终端状态。否则我们需要考虑状态的排序等。它还假设所有订单都有项目,因为任何状态下没有项目的订单也符合标准。后者似乎是一个非常安全的假设。

答案 1 :(得分:1)

这有点棘手,因为它不仅仅是一个简单的加入&#34;。有几种方法可以解决这个问题。一种方法使用聚合和having子句:

select op.order_id
from order_products op
group by op.order_id
having sum(case when op.status = 'shipped' then 1 else 0 end) = count(*);

也就是说,计算状态为已发货的行数,并确保它是给定行的所有行。如果您想了解有关订单的更多信息,请同时加入该表。

另一种方法使用join,如下所示:

select op.*
from orders o join
     order_products op
     on o.order_id = op.orderId and op.status <> 'shipped';

这将返回所有没有发货状态的产品实例。如果您只想要订单信息,可以使用select distinct o.*代替select op.*