我应该使用什么mysql查询来选择与我的所有条件匹配的类别?
我的表中有以下数据,称为cat_product我应该使用什么mysql查询来选择与我的所有条件匹配的类别?,sql,mysql,Sql,Mysql,我的表中有以下数据,称为cat_product cat_id product_id 1 2 1 3 2 2 2 4 如果给定一组product_id(2,3)的值,我想知道唯一的cat_id。在本例中,这将是cat_id 1 我应该如何构造mysql查询 我试着用 select distinct cat_id from cat_product where product_id IN (2,3) 但它同时返回1和2 如果
cat_id product_id
1 2
1 3
2 2
2 4
如果给定一组product_id(2,3)的值,我想知道唯一的cat_id。在本例中,这将是cat_id 1
我应该如何构造mysql查询
我试着用
select distinct cat_id from cat_product where product_id IN (2,3)
但它同时返回1和2
如果我使用
select distinct cat_id from cat_product where product_id NOT IN (2,3)
我得到2
还有比这更好的方法吗
select distinct cat_id from cat_product where product_id IN (2,3)
and cat_id NOT IN
(select distinct cat_id from cat_product where product_id NOT IN (2,3) )
我需要返回具有我要查找的确切产品id集的category_id
基本上,我有大约10个产品ID作为输入。您自己的解决方案将不起作用(至少如果我正确理解问题的话)。它将返回一个类别的id,该类别包含所列产品的一个或多个和否其他产品。尝试将以下行添加到表中,并查看是否得到预期结果:
insert into cat_product (cat_id, product_id) values (1,5)
如果您确实需要查找包含所列产品的所有的类别的id(无论该类别中可能有哪些其他产品),请尝试以下查询:
select cat_id
from cat_product
where product_id in (2,3)
group by cat_id
having count(*) = 2
查询最后一行的数字2
对应于您正在搜索的产品集的大小。如果使用某些参数化API执行查询,请确保创建绑定到productsArray.length
或类似文件的附加参数
SELECT * FROM
(SELECT cat_id FROM cat_product WHERE product_id=2) a
INNER JOIN
(SELECT cat_id FROM cat_product WHERE product_id=3) b
ON a.cat_id = b.cat_id;
您需要在(cat\u id,product\u id)
(按此顺序)上有一个唯一的
索引才能快速工作
此解决方案将使用分组依据的索引来获取不同类别的列表,并且存在的谓词将比计数(*)
快一点(因为聚合需要一些开销)
如果要搜索两个以上的产品,请相应地将第一个参数调整为LIMIT
它应该是限制n-1,1
,其中n
是列表中的项数
更新:
要返回包含列表中所有产品的类别,而不返回其他内容,请使用以下命令:
SELECT cat_id
FROM (
SELECT DISTINCT cat_id
FROM cat_product
) cpo
WHERE EXISTS
(
SELECT NULL
FROM cat_product cpi
WHERE cpi.cat_id = cpo.cat_id
AND product_id IN (2, 3)
LIMIT 1, 1
)
AND NOT EXISTS
(
SELECT NULL
FROM cat_product cpi
WHERE cpi.cat_id = cpo.cat_id
AND product_id NOT IN (2, 3)
)
查找包含所有给定产品而不包含其他内容的cat_id
让我们创建一些测试数据
create table cat_product (
cat_id int not null,
product_id int not null,
primary key (cat_id, product_id));
delete from cat_product;
insert into cat_product
values
(1, 2),
(1, 3),
(2, 2),
(2, 4),
(3, 1),
(3, 2),
(3, 3),
(3, 4),
(3, 5),
(4, 1),
(4, 2),
(4, 3),
(4, 4),
(4, 6),
(5, 1),
(5, 2),
(5, 3),
(5, 4),
(5, 5),
(5, 6);
在(1,2,3,4,5)
和在cats.match\u count=5处插入查询最后一行的产品标识号
select
cats.cat_id
from
/* Count how many products for each cat match the list of products */
(select
cp.cat_id,
count(*) as match_count
from
cat_product cp
where
cp.product_id IN (1, 2, 3, 4, 5)
group by
cp.cat_id) as cats,
/* Count the number of products in each cat */
(select cat_id, count(*) as cat_count
from cat_product
group by cat_id) as cat_count
where
cats.cat_id = cat_count.cat_id
/* We matched all the products in the cat */
and cats.match_count = cat_count.cat_count
/* We matched all the products we wanted. Without this clause
the query would also match cats that only contain products in
our list (but not all of them) */
and cats.match_count = 5;
您正在寻找的是如果我的产品id有大约10个值会怎么样?基本上是(2,3,5,7,8,11,12,13,14,20)?和(2,3)中的产品id这里有错误吗?它是cpi.product\u id还是cpo.product\u idcpo
不返回product\u id
,因此它是cpi.product\u id
。没有错误,但如果需要,可以在别名前加前缀。此查询将返回包含所有列出的产品的任何类别,也可能返回其他产品。根据OP对我的回答的评论,这不是期望的行为。我需要返回类别id,该类别id具有我要查找的产品id的精确集。如“精确”和“无其他”?是的,精确,无其他。我提出的复杂问题对我来说很有用。我需要问问是否有更好更快的方法。所有类别都有10种产品,每个类别对应10种产品。我不相信您当前的解决方案会给出正确的结果-请参阅我答案的前四行。
select
cats.cat_id
from
/* Count how many products for each cat match the list of products */
(select
cp.cat_id,
count(*) as match_count
from
cat_product cp
where
cp.product_id IN (1, 2, 3, 4, 5)
group by
cp.cat_id) as cats,
/* Count the number of products in each cat */
(select cat_id, count(*) as cat_count
from cat_product
group by cat_id) as cat_count
where
cats.cat_id = cat_count.cat_id
/* We matched all the products in the cat */
and cats.match_count = cat_count.cat_count
/* We matched all the products we wanted. Without this clause
the query would also match cats that only contain products in
our list (but not all of them) */
and cats.match_count = 5;