我觉得我太过于复杂的问题。我有一个情况我有2个表:挣扎着一个简单的JOIN
orders:
- order_id
order_products:
- order_id
- status
如果每个订单的产品能有一个独立的状态(例如:发货,延期交货等),我希望能够编写一个查询说“让我看看所有产品全部发货的订单。“
我觉得我太过于复杂的问题。我有一个情况我有2个表:挣扎着一个简单的JOIN
orders:
- order_id
order_products:
- order_id
- status
如果每个订单的产品能有一个独立的状态(例如:发货,延期交货等),我希望能够编写一个查询说“让我看看所有产品全部发货的订单。“
这是一个有点棘手,因为它比“简单连接”等等。有几种方法可以解决这个问题。一种方法是使用聚合和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.*
。
这样做的一种方法是查找所有订单,其中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。
这当然假定发货是终端状态。否则,我们需要考虑状态排序等。它还假定所有订单都有项目,因为没有任何状态项目的订单也会符合标准。后者似乎是一个非常安全的假设。