在不使用表连接的情况下计算按 ID 分组的匹配评级?可能吗? MYSQL?

Posted

技术标签:

【中文标题】在不使用表连接的情况下计算按 ID 分组的匹配评级?可能吗? MYSQL?【英文标题】:Counting matching ratings grouped by ID without using table joins? Is it possible? MYSQL? 【发布时间】:2016-11-17 16:43:36 【问题描述】:

我有一个名为 ratingPerId 的中间表,它是从此处显示的存储过程生成的:

Id   Rating
'1', 'low'
'1', 'low'
'1', 'low'
'1', 'low'
'1', 'low'
'2', 'medium'
'2', 'medium'
'2', 'medium'
'2', 'high'
'2', 'high'
'4', 'high'
'4', 'high'
'4', 'high'
'4', 'high'
'4', 'high'
'9', 'high'
'9', 'high'
'9', 'high'
'9', 'high'
'9', 'high'
'9', 'high'
'9', 'high'
'9', 'high'
'9', 'high'

我想要的是 Id 1,计算所有的低、中、高。并对以下所有 ID 2、4、9 等执行相同操作...

现在我拥有的是一个计算每个 ID 的高点和低点的表连接:

drop temporary table if exists t1, t2;
create temporary table t1(ruleid int, high INT);
INSERT into t1(
    SELECT ruleid, count(*) AS High from ratingsPerRuleId  WHERE rating='high' group by ruleid);
create temporary table t2(ruleid int, low int);
INSERT into t2(
    SELECT ruleid, count(*) AS Low from ratingsPerRuleId WHERE rating='low' group by ruleid);

SELECT t1.RuleID, t1.high, t2.low from t1 left join t2 on t1.ruleid=t2.ruleid ;

ID   High  Low
1    NULL   5
2     2    NULL
4     5    NULL
9     9    NULL

如您所见,我需要为 Medium 创建第三个表,然后将其连接起来以获取 Medium 列。

mysql 中有没有更简单的方法来做到这一点?我觉得有一个简单的语句可以做到这一点,而我的小表凌乱的表连接不是必需的,但我对 MYSQL 了解不够,无法得到答案。

我查看了 Count(distinct) 和 Select Distinct 但没有找到答案。

谢谢!

【问题讨论】:

你想要这样的结果:对于每个 ID 总高、总中和总低计数? 是的!我想要这样的结果 【参考方案1】:

我猜你需要使用CASE WHEN 表达式。

SELECT 
 Id,
 COUNT(CASE WHEN Rating ='high' THEN 1 END) AS high,
 COUNT(CASE WHEN Rating ='medium' THEN 1 END) AS medium,
 COUNT(CASE WHEN Rating ='low' THEN 1 END) AS low
FROM your_table
GROUP BY Id;

Working Demo

或者如果您不想使用CASE WHEN,可以使用SUMMySQL boolean expression

SELECT 
 Id,
 SUM(Rating ='high') AS high,
 SUM(Rating ='medium') AS medium,
 SUM(Rating ='low') AS low
FROM your_table
GROUP BY Id;

Working Demo

注意:SELECT SUM(a=b) returns 1 only if a=b;

注意: 工作演示中使用了以下示例输入

| Id | Rating |
|----|--------|
|  1 |    low |
|  1 |    low |
|  1 | medium |
|  1 |   high |
|  2 |   high |

【讨论】:

工作就像一个魅力,谢谢!我什至不知道 CASE WHEN 太方便了!我建议通过CASE WHEN 上的教程。 :) 您还可以查看基于SUM 的更新答案。 @松露【参考方案2】:

这应该可以工作(COUNT 不包括空值):

SELECT ruleid
  , COUNT(IF(rating = 'high', 1, NULL)) AS High 
  , COUNT(IF(rating = 'medium', 1, NULL)) AS Medium 
  , COUNT(IF(rating = 'low', 1, NULL)) AS Low 
FROM ratingsPerRuleId 
GROUP BY ruleid
;

此外,如果您愿意,可以将 COUNT(..., NULL)) 替换为 SUM(..., 0))

注意:1000111 的答案更便携,因为旧版本的 MS SQL 不支持 IF(...)

【讨论】:

以上是关于在不使用表连接的情况下计算按 ID 分组的匹配评级?可能吗? MYSQL?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不重复员工 ID 的情况下计算表中的姓氏

如何在不考虑时间的情况下按日期时间列分组

按 varchar 字段的一部分分组

如何在不使用 SQL 中的多个连接条件的情况下获取同一行中的所有值?

在不破坏顺序的情况下对列进行分组

如何在不计算第二个表中的双打的情况下建立连接? [复制]