sql select 所有如果列只有两个特定值
sql select all if column has only two particular values
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),
)
如何 select 所有只有 id = 1 和 id = 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)
有多种方法可以获得所需的结果,这利用了条件聚合:
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
)
取决于 indexes/selectivity 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
我会使用聚合来做到这一点 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
table。
你的问题就是我所说的 "set-within-set" 查询。 . .在层次结构中寻找模式(即订单中的产品)。有几种方法可以解决这个问题,但 having
子句非常通用。
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),
)
如何 select 所有只有 id = 1 和 id = 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)
有多种方法可以获得所需的结果,这利用了条件聚合:
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
)
取决于 indexes/selectivity 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
我会使用聚合来做到这一点 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
table。
你的问题就是我所说的 "set-within-set" 查询。 . .在层次结构中寻找模式(即订单中的产品)。有几种方法可以解决这个问题,但 having
子句非常通用。