如果列只有两个特定值,则sql select all

时间:2015-10-05 21:02:12

标签: mysql sql select foreign-keys inner-join

orders (
  o_id INT AUTO_INCREMENT,
  o_status TINYINT,
  o_description VARCHAR(50),
)

orders_products (
  op_id INT AUTO_INCREMENT,
  op_order_id INT(11),
  op_product_id INT(11),
  op_price DECIMAL(19, 2),
)

如何选择仅包含id = 1且id = 2的产品的所有订单。

谢谢你,对不起我的英文......

3 个答案:

答案 0 :(得分:3)

有不同的方法可以获得所需的结果,这利用了条件聚合:

select *
from orders 
where o_id in
 (
   select op_order_id 
   from orders_products
   having count(case when op_product_id = 1 then 1 end) > 0 -- at least one row with 1
      and count(case when op_product_id = 2 then 1 end) > 0 -- at least one row with 2
      and count(case when op_product_id not in (1,2) then 1 end) = 0 -- no other value 
 )

取决于索引/选择性EXISTS / NOT EXISTS可能会更快:

select o_id
from orders as o
where exists (select * 
              from orders_products as op
              where op.op_order_id = o.o_id 
                and op.op_product_id = 1)  -- at least one row with 1
  and exists (select * 
              from orders_products as op
              where op.op_order_id = o.o_id 
                and op.op_product_id = 2)  -- at least one row with 2
  and not exists (select * 
                  from orders_products as op
                  where op.op_order_id = o.o_id 
                    and op.op_product_id not in (1,2))  -- no other value

答案 1 :(得分:2)

您可以先找到产品1或2或两者的所有不同订单和产品组合,然后查找同时具有这两种产品的订单。

create table orders (o_id INT);
create table orders_products (op_order_id INT(11), op_product_id INT(11));

insert into orders values (1), (2);
insert into orders_products values (1, 1), (1, 2), (2, 2);

select o_id from (
  select distinct o_id, op_product_id
  from orders o
  inner join orders_products op on op.op_order_id = o.o_id
  where op.op_product_id in (1,2)
) main
group by o_id 
having count(*) = 2

Result:
1

编写查询的另一种方法可能是这样的:

select o_id
from orders o
where exists (select 1 from orders_products where op_order_id = o.o_id and op_product_id = 1)
and exists (select 1 from orders_products where op_order_id = o.o_id and op_product_id = 2)

答案 2 :(得分:1)

我会使用聚合和having

来做到这一点
select order_id
from order_products op
group by order_id
having sum(product_id = 1) > 0 and
       sum(product_id = 2) > 0 and
       sum(product_id not in (1, 2)) = 0;

如果您想了解订单的其他信息,请加入orders表。

您的问题是我称之为“set-within-set”查询。 。 。寻找层次结构中的模式(即订单中的产品)。有几种方法可以解决这个问题,但having条款非常普遍。