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的产品的所有订单。
谢谢你,对不起我的英文......
答案 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
条款非常普遍。