2015-06-20 72 views
0

我觉得我太过于复杂的问题。我有一个情况我有2个表:挣扎着一个简单的JOIN

orders: 
- order_id 

order_products: 
- order_id 
- status 

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

回答

1

这是一个有点棘手,因为它比“简单连接”等等。有几种方法可以解决这个问题。一种方法是使用聚合和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.*

2

这样做的一种方法是查找所有订单,其中NOT EXISTS处于非发货状态。

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。

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