我应该用什么mysql查询来选择符合我所有标准的类别?

时间:2010-01-29 11:37:08

标签: 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.

如果我使用

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作为输入。

5 个答案:

答案 0 :(得分:1)

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
        )

您需要UNIQUE上的(cat_id, product_id)索引(按此顺序),以便快速开展此工作。

此解决方案将使用INDEX FOR GROUP BY获取不同类别的列表,EXISTS谓词将比COUNT(*)快一点(因为聚合需要一些开销)。

如果要搜索的产品超过两种,请相应地将第一个参数调整为LIMIT

应为LIMIT n - 1, 1,其中nIN列表中的项目数。

<强>更新

要从列表中返回包含所有产品的类别,请使用以下命令:

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)
        )

答案 1 :(得分:0)

你自己的解决方案不起作用(至少如果我没有正确理解问题的话)。它将返回包含一个或多个所列产品的类别的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或类似的附加参数。

答案 2 :(得分:0)

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;

答案 3 :(得分:0)

找到包含所有给定产品的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);

插入cp.product_id IN (1, 2, 3, 4, 5)的product_id列表 AND cats.match_count = 5的查询的最后一行插入product_id的数量。

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;

答案 4 :(得分:0)

你正在寻找

Relational Division