在我的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
可以轻松获得一个类别中的文章计数但是如何扩展此查询以检查两只猫?
答案 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
的模式确实过早了。