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

问题描述:

我有一个名为ratingsPerId中间表是从这里显示的存储过程产生的:计算不使用表连接而按ID分组的匹配评级?可能吗? MYSQL?

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' 

我要的是编号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(不同)和Select Distinct,但没有找到答案。

谢谢!

+0

你想结果是这样的:每个ID的总高,总中,总的低数量? – 1000111

+0

是的!我想要那样的结果 – truffle

我想你需要使用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

OR可以使用与MySQL boolean expression沿SUM,如果你不希望使用CASE WHEN

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;

NB:下面的示例输入在工作演示使用

​​
+0

像魅力一样工作,谢谢!我什至不知道CASE当 – truffle

+1

这太方便了!我会建议通过一个关于'CASE WHEN'的教程。 :) – 1000111

+1

你也可以看看基于'SUM'的更新答案。 @truffle – 1000111

这应该工作(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 
; 

此外,如果你喜欢,你可以用SUM(..., 0))取代COUNT(..., NULL))

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

+0

这工作完美!谢谢! – truffle