2

在我的 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

4 回答 4

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
于 2013-02-08T19:29:53.917 回答
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 可以使用索引来避免全表扫描。

于 2013-02-08T19:31:21.567 回答
-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
于 2013-02-08T19:28:44.130 回答
-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,这一切都还为时过早,没有看到s_a_c.

于 2013-02-08T19:28:48.167 回答