简体   繁体   English

SQL:获取两类文章的数量

[英]SQL: get count of articles in two categories

In my MySQL db I have a table storing the association of articles and categories, columns are category_id and product_id. 在我的MySQL数据库中,我有一个表,用于存储文章和类别的关联,列为category_id和product_id。 So the article #5 belonging to categories #3 and #6 has the rows (3,5)(6,5). 因此,属于类别#3和#6的商品#5具有(3,5)(6,5)行。

Now I need to get the count of articles which are both in category 1 and 6. Getting the count of articles in one category is easy with SELECT count(category_id) from s_a_c where category_id=1 but how do I expand this Query to check for two cats? 现在,我需要获取类别1和类别6中的文章数。 SELECT count(category_id) from s_a_c where category_id=1可以轻松地获得一个类别中的文章数, SELECT count(category_id) from s_a_c where category_id=1但是如何扩展此查询以检查两只猫?

Here's one way with two joins (one join for each category you want to search for): 这是带有两个联接的一种方法(对于要搜索的每个类别一个联接):

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

And here's another way with a HAVING clause. 这是带有HAVING子句的另一种方法。 The derived table pulls all products from s_a_c with category 1 and 6, having both ( COUNT(1) = 2 ). 派生表从s_a_c中提取类别1和6都具有( COUNT(1) = 2 )的所有乘积。 This takes advantage of the fact that {product_id, category_id} will be unique: 这利用了{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

You need to group your table by product, then filter the groups for those that match your desired criteria (using the HAVING clause, which is evaluated after grouping whereas WHERE clauses are evaluated before grouping): 您需要按产品对表进行分组,然后针对与所需条件匹配的组过滤组(使用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

If (product_id,category_id) are guaranteed to be unique (eg through a uniqueness constraint enforced by a UNIQUE key), you can use the more performant COUNT(*) in place of COUNT(DISTINCT category_id) . 如果(product_id,category_id)保证是唯一的(例如,通过UNIQUE键强制的唯一性约束),则可以使用性能更高的COUNT(*)代替COUNT(DISTINCT category_id)

If you need to implement more complex logic on the group filter, you can take advantage of MySQL's lack of genuine boolean types thus: 如果需要在组过滤器上实现更复杂的逻辑,则可以利用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)

Note that I continue to include a WHERE clause in order that MySQL can use an index to avoid a full table scan if possible. 请注意,我继续包括WHERE子句,以便MySQL尽可能使用索引来避免全表扫描。

To get all articles (may have duplicates) in two categories (one and two) 要获取两个类别(一和两)中的所有文章(可能有重复项)

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

To get all articles (without duplicates) in two categories (one and two) 获取两个类别(一个和两个)中的所有文章(无重复)

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

EDIT: Misread - this original query does if exists in either or category: 编辑:误读-此原始查询会在或类别中存在:

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

The correct query for existing in BOTH categories: 现有两个类别中的正确查询:

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

TBH, this all really premature w/o seeing the schema for s_a_c . TBH,这真的不成熟,没有看到s_a_c的模式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM