检索没有特定项目的订单号

时间:2010-08-16 18:41:58

标签: sql mysql

我有一张包含一些冰淇淋订单数据的表格如下:

id  order_number  item_name
1   1             cake cone
2   1             sprinkles
3   2             sugar cone
4   3             semi-sweet morsels
5   3             sprinkles

(这比真实表更简单,但存在相关列。)

基本上我想要做的是生成一个不包含特定项目(糖锥和蛋糕锥)的订单号列表。

我在这一点上尝试的似乎有效,但我想知道是否有更好的方法:

select a.order_number from 
(select order_number from orders where (item_name != 'sugar cone' and item_name != 'cake cone') group by order_number)a
left join
(select order_number from orders where (item_name = 'sugar cone' or item_name = 'cake cone') group by order_number)b
on a.order_number = b.order_number
where b.order_number is null;

这将返回我期望的order_numbers(在这种情况下,只有3阶),但对我来说似乎很笨拙。

你有更好的方法吗?

4 个答案:

答案 0 :(得分:4)

使用LEFT JOIN / IS NULL:

   SELECT x.order_number
     FROM ORDERS x
LEFT JOIN ORDERS y ON y.order_number = x.order_number
                  AND y.item_name IN ('sprinkles', 'sugar cone')
    WHERE y.id IS NULL

使用NOT EXISTS

   SELECT x.order_number
     FROM ORDERS x
    WHERE NOT EXISTS(SELECT NULL
                       FROM ORDERS y
                      WHERE y.item_name IN ('sprinkles', 'sugar cone')
                        AND y.order_number = x.order_number)

使用NOT IN

   SELECT x.order_number
     FROM ORDERS x
    WHERE x.order_number NOT IN(SELECT y.order_number
                        FROM ORDERS y
                      WHERE y.item_name IN ('sprinkles', 'sugar cone'))

摘要

在MySQL上,if the column(s) being joined on are not nullable - LEFT JOIN/IS NULL is the fastest/most efficient。否则,NOT EXISTS & NOT IN are better choices

结论

由于加入了不能为NULL的列,因此LEFT JOIN / IS为最佳选择。

答案 1 :(得分:3)

使用EXISTS子句将比使用IN子句提供更好的性能。

SELECT a.order_number
  FROM orders a
 WHERE NOT EXISTS (SELECT 1
                     FROM orders b
                    WHERE b.item_name IN ('sugar cone', 'cake cone')
                          AND b.order_number = a.order_number);

答案 2 :(得分:2)

select order_number
from orders 
where order_number not in (
    select order_number
    from orders 
    where item_name in ('sprinkles', 'sugar cone')
)

答案 3 :(得分:1)

select distinct order_number from orders where order_number not in 
    (select order_number from orders where item_name in ('sugar cone', 'cake cone'))