sql select 个订单不包含某些商品

sql select orders not containing certain items

数据库有 3 个表,"items"、"orders" 和 "orderitems",它们代表一个 N:N 关系。我需要找到不包含某些项目的订单。例如,我想获取所有不包括苹果、橙子或香蕉的订单。

我试过:

SELECT * FROM orders o, 
LEFT JOIN orderitems oi ON o.order_id=oi.order_id
LEFT JOIN items i ON oi.item_id=i.item_id
WHERE
   i.name NOT IN ('banana', 'apple', 'orange')

没用。它 returns 所有订单,只要它们至少包含不同于 'banana'、'apple' 和 'orange' 的项目。

我考虑过 "NOT IN" 对包含这些项目的所有订单进行子选择,但它会非常慢,因为子选择将获得几乎所有订单(数百万个结果)。

已更新

请尝试:

SELECT * FROM orders o
WHERE o.order_id
  NOT IN
  (
        SELECT oi.order_id 
        FROM orderitems oi 
        INNER JOIN items i ON oi.item_id=i.item_id
        WHERE
           i.name IN ('banana', 'apple', 'orange')

    )

尝试使用 group byhaving:

SELECT oi.order_id
FROM orderitems oi JOIN
     items i
     ON oi.item_id=i.item_id
GROUP BY oi.order_id
HAVING SUM(i.name IN ('banana', 'apple', 'orange')) = 0;

如果你想要完整的订单信息,你可以加入 orders table 回来。

您还可以使用:

select *
  from orders o
  left join (select o.order_id
               from orders o
               join orderitems oi
                 on o.order_id = oi.order_id
               join items i
                 on oi.item_id = i.item_id
              where i.name in ('banana', 'apple', 'orange')) v
    on o.order_id = v.order_id
  left join orderitems oi
    on o.order_id = oi.order_id
  left join items i
    on oi.item_id = i.item_id
 where v.order_id is null

听起来您想获取所有包含您正在查看的商品的订单,然后从结果集中排除这些订单。

SELECT * 
FROM orders o
    LEFT JOIN (select order_id 
                from orderitems oi 
                    inner join items i ON oi.item_id=i.item_id
                WHERE i.name IN ('banana', 'apple', 'orange')
                ) x
        ON o.order_id=x.order_id
WHERE x.order_id is null