过滤具有一个项目且同时没有另一个项目的订单

时间:2015-10-22 11:16:34

标签: mysql sql

我有一个非常简单的一对多关系(表格订单 - 项目),其中一个订单可以包含零个或多个项目。

在同一时间过滤只有item1(item_id = 1)和没有item2(item_id = 2)的订单的最佳方法(SQL查询)是什么?

目前我使用以下SQL查询:

SELECT o.order_id
  FROM orders o
  JOIN items i ON i.order_id=o.order_id
 WHERE i.item_id=1
   AND o.order_id NOT IN (SELECT o2.order_id
                            FROM orders o2
                            JOIN items i2 ON i2.order_id=o2.order_id
                           WHERE i2.item_id=2)

2 个答案:

答案 0 :(得分:2)

我更喜欢使用group byhaving

来处理这些类型的问题
SELECT i.order_id
FROM items i
GROUP BY i.order_id
HAVING SUM(i.item_id = 1) > 0 AND
       SUM(i.item_id = 2) = 0;

一些注意事项:

  • 您不需要加入orders,因为order_id中有items
  • having子句中的每个条件都是计算项目数。第一个说项目1中至少有一个,第二个项目没有项目2。
  • 我删除了where子句。如果你有一个,那么它将是WHERE i.item_id IN (1, 2)

编辑:

在除MySQL之外的任何数据库中,您将使用此HAVING子句:

HAVING SUM(CASE WHEN i.item_id = 1 THEN 1 ELSE 0 END) > 0 AND
       SUM(CASE WHEN i.item_id = 2 THEN 1 ELSE 0 END) = 0;

这也适用于MySQL;我只是喜欢较短的符号。

答案 1 :(得分:1)

不需要相关子查询,请使用HAVING子句。

这排除了item_id = 2所在的所有order_id

SELECT o.order_id
FROM orders o
JOIN items i ON i.order_id=o.order_id
WHERE i.item_id=1
GROUP BY o.order_id
HAVING SUM(item_id = 2) = 0;

或者你可以做到

SELECT o.order_id
FROM orders o
JOIN items i ON i.order_id=o.order_id
WHERE i.item_id=1
GROUP BY o.order_id
HAVING COUNT(DISTINCT item_id) = 1;

确保它只有item_id = 1。有几种方法,取决于你想要做什么。