如何找到包含所有可用产品的订单?
How do I find an order that contains all the available products?
我有一个包含所有可用产品的 products table,以及 order_has_product table 其中包含每个订单中应包含的所有产品。
如何找到包含所有可用产品的任何订单的 order_id?
请注意 order_id 为 1 的订单如何包含所有可用产品。
order_has_product:
order_id
product_id
1
7
1
8
1
9
2
7
3
8
产品:
product_id
name
7
shovel
8
rake
9
scythe
这是我目前拥有的:
SELECT order_id
FROM order_has_product
WHERE product_id = ALL (
SELECT product_id
FROM products
);
ALL
means that the condition will be true only if the operation is true for all values in the range.
所以 ALL =
可能不是你所期望的,但是我们可以尝试使用 >=
来匹配 order_has_product
中最大的 product_id。
SELECT order_id
FROM order_has_product
WHERE product_id >= ALL (
SELECT product_id
FROM products
);
否则,如果我从你的逻辑中理解正确,我们可以尝试使用EXISTS
子查询来实现。
SELECT ohp.order_id
FROM (
SELECT order_id,COUNT(DISTINCT product_id) cnt
FROM order_has_product ohp
WHERE EXISTS (SELECT 1 FROM products p WHERE p.product_id = ohp.product_id)
GROUP BY order_id
) ohp
WHERE EXISTS (
SELECT 1
FROM products p
HAVING COUNT(*) = ohp.cnt
)
这是使用 GROUP_CONCAT
的另一种方法:
SELECT order_id FROM order_has_product
GROUP BY order_id
HAVING GROUP_CONCAT(DISTINCT product_id)=(SELECT GROUP_CONCAT(product_id) FROM products)
ORDER BY product_id;
此查询比较串联的产品 ID,这将检查一个 ID 是否包含产品 table.
中列出的所有 product_id
结果
order_id
----------
1
MySQL GROUP_CONCAT() function returns a string with concatenated non-NULL value from a group
检查 MySQL GROUP_CONCAT() function 以获取 GROUP_CONCAT
的更多详细信息和示例。
如果通过 如何找到包含所有可用产品的任何订单的order_id个人 order_id 购买了您产品中的所有东西 table(换句话说,大手笔 order_id),其他人已经为您提供了答案。但是,如果你想知道一个人 order_id 是否有一个 product_id 而不是在产品 table 中的 product_id (换句话说,是否已经准备好发货),我可以帮助。
create table order_has_product (order_id int,product_id int);
insert order_has_product values(1,7),(1,8),(1,9),(2,7),(3,8);
create table products (product_id int,name varchar(10));
insert products values(7,'shovel'),(9,'scythe'); -- order_id 8 is removed from the table for better demonstration
select order_id,
min(if(product_id in (select product_id from products),'yes','no')) as has_everything_ready
from order_has_product
group by order_id
;
我有一个包含所有可用产品的 products table,以及 order_has_product table 其中包含每个订单中应包含的所有产品。
如何找到包含所有可用产品的任何订单的 order_id?
请注意 order_id 为 1 的订单如何包含所有可用产品。
order_has_product:
order_id | product_id |
---|---|
1 | 7 |
1 | 8 |
1 | 9 |
2 | 7 |
3 | 8 |
产品:
product_id | name |
---|---|
7 | shovel |
8 | rake |
9 | scythe |
这是我目前拥有的:
SELECT order_id
FROM order_has_product
WHERE product_id = ALL (
SELECT product_id
FROM products
);
ALL
means that the condition will be true only if the operation is true for all values in the range.
所以 ALL =
可能不是你所期望的,但是我们可以尝试使用 >=
来匹配 order_has_product
中最大的 product_id。
SELECT order_id
FROM order_has_product
WHERE product_id >= ALL (
SELECT product_id
FROM products
);
否则,如果我从你的逻辑中理解正确,我们可以尝试使用EXISTS
子查询来实现。
SELECT ohp.order_id
FROM (
SELECT order_id,COUNT(DISTINCT product_id) cnt
FROM order_has_product ohp
WHERE EXISTS (SELECT 1 FROM products p WHERE p.product_id = ohp.product_id)
GROUP BY order_id
) ohp
WHERE EXISTS (
SELECT 1
FROM products p
HAVING COUNT(*) = ohp.cnt
)
这是使用 GROUP_CONCAT
的另一种方法:
SELECT order_id FROM order_has_product
GROUP BY order_id
HAVING GROUP_CONCAT(DISTINCT product_id)=(SELECT GROUP_CONCAT(product_id) FROM products)
ORDER BY product_id;
此查询比较串联的产品 ID,这将检查一个 ID 是否包含产品 table.
中列出的所有 product_id结果
order_id
----------
1
MySQL GROUP_CONCAT() function returns a string with concatenated non-NULL value from a group
检查 MySQL GROUP_CONCAT() function 以获取 GROUP_CONCAT
的更多详细信息和示例。
如果通过 如何找到包含所有可用产品的任何订单的order_id个人 order_id 购买了您产品中的所有东西 table(换句话说,大手笔 order_id),其他人已经为您提供了答案。但是,如果你想知道一个人 order_id 是否有一个 product_id 而不是在产品 table 中的 product_id (换句话说,是否已经准备好发货),我可以帮助。
create table order_has_product (order_id int,product_id int);
insert order_has_product values(1,7),(1,8),(1,9),(2,7),(3,8);
create table products (product_id int,name varchar(10));
insert products values(7,'shovel'),(9,'scythe'); -- order_id 8 is removed from the table for better demonstration
select order_id,
min(if(product_id in (select product_id from products),'yes','no')) as has_everything_ready
from order_has_product
group by order_id
;