SQL:获取两个类别的文章计数

时间:2013-02-08 19:26:59

标签: php mysql

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

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

4 个答案:

答案 0 :(得分: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 :(得分:1)

您需要按产品对表进行分组,然后根据所需条件过滤组(使用HAVING子句,分组后评估 {{1} 分组之前评估}子句:

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

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

COUNT(DISTINCT category_id)

请注意,我继续包含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) 子句,以便MySQL可以使用索引来避免全表扫描。

答案 2 :(得分:-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

答案 3 :(得分:-1)

编辑:误读 - 如果原始查询存在于任何一个或类别中,则会发生错误:

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

对BOTH类别中现有的正确查询:

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

TBH,这对于看到s_a_c的模式确实过早了。