2013-02-08 33 views
2

在我的MySQL数据库中,我有一个存储文章和类别关联的表,列是category_id和product_id。因此,属于类别#3和#6的文章#5具有行(3,5)(6,5)。SQL:获得两类文章的计数

现在我需要获得同类型1和类别6的文章数。通过SELECT count(category_id) from s_a_c where category_id=1可以轻松获得一个类别的文章数,但是如何扩展此查询以检查两只猫?

回答

2

这里有两个单向连接(一个连接你要搜索的每个类别):

SELECT COUNT(1) 
FROM articles 
INNER JOIN s_a_c c1 ON articles.product_id = c1.product_id 
    AND c1.category_id = 1 
INNER JOIN s_a_c c2 ON articles.product_id = c2.product_id 
    AND c2.category_id = 6 

这里还有一个HAVING条款的另一种方式。派生表将s_a_c中的所有产品与类别1和6一起提供,并且都具有(COUNT(1) = 2)。这需要的事实{product_id, category_id}将是独特的优势:

SELECT COUNT(1) 
FROM 
(
    SELECT product_id 
    FROM s_a_c 
    WHERE category_id IN (1,6) 
    GROUP BY product_id 
    HAVING COUNT(1) = 2 
) x 
-1

要获得所有文章(可能有重复)两类(一和二)

SELECT count(category_id) from s_a_c where category_id=1 or category_id=2 

要获得所有文章(不重复)两类(一和二)

SELECT count(category_id) FROM s_a_c WHERE category_id=1 or category_id=2 GROUP BY article_id 
+2

一个Category_id不能同时有两个值 – Taryn 2013-02-08 19:29:08

+0

我的歉意,用OR代替 – 2013-02-08 19:31:20

+0

@bluefeet评论说,由于不可能的WHERE子句,这些查询中的第一个不会返回任何结果(也就是说, category_id'不能同时等于1和2);第二个查询将返回* * *类别(不是两个类别)中的每篇文章的记录,而且每个结果仅包含将该文章与类别1或2相关联的记录数。最确定不是OP之后的事情。 -1 – eggyal 2013-02-08 19:41:35

-1

编辑:误读 - 这个原来的查询确实存在,如果在任一或类别:

SELECT COUNT(*) FROM s_a_c WHERE category_id IN (1,6);

现有两个类别正确的查询:

SELECT COUNT(*) FROM s_a_c WHERE category_id = 1 AND category_id 6;

TBH,这一切真的过早W/O看到架构s_a_c

+2

相同的字段不能同时有两个不同的值 – 2013-02-08 19:36:07

1

你需要按产品你的表,然后筛选组为那些符合所需标准(使用HAVING条款,这是后评估分组而WHERE子句进行评估之前分组):

SELECT COUNT(*) FROM (
    SELECT article_id 
    FROM  s_a_c 
    WHERE category_id IN (1,6) 
    GROUP BY product_id 
    HAVING COUNT(DISTINCT category_id) = 2 
) t 

如果(product_id,category_id)被保证是唯一的(例如。通过由UNIQUE键执行的唯一性约束),您可以使用更高性能的COUNT(*)代替COUNT(DISTINCT category_id)

如果您需要实现对组过滤器更复杂的逻辑,你可以利用MySQL的缺乏真正的布尔类型的这样:

SELECT article_id 
FROM  s_a_c 
WHERE category_id IN (1,3,6) 
GROUP BY product_id 
HAVING SUM(category_id = 1) 
    AND SUM(category_id = 6) 
    AND NOT SUM(category_id = 3) 

注意,我继续包括WHERE条款,以便MySQL的如果可能的话,可以使用索引来避免全表扫描。