Mysql 比较行并获取百分比

Mysql 比较行并获取百分比,mysql,sql,Mysql,Sql,我发现很难找到一个合适的标题。为简单起见,假设我有下表: cook_id cook_rating 1 2 1 1 1 3 1 4 1 2 1 2 1 1 1 3 1 5 1 4 2 5 2 2 现在我想得到一个“好”厨师的输出。一个好厨师的评分至少为1分、2分或3分的70%,而不是4分或5分 所以在我的示例表中,id为1的cook总共有10个等级,其中

我发现很难找到一个合适的标题。为简单起见,假设我有下表:

cook_id cook_rating
1       2
1       1
1       3
1       4
1       2
1       2
1       1
1       3
1       5
1       4
2       5
2       2
现在我想得到一个“好”厨师的输出。一个好厨师的评分至少为1分、2分或3分的70%,而不是4分或5分

所以在我的示例表中,id为1的cook总共有10个等级,其中7个等级有类型1、2和3。只有三个有类型4或5。因此,id为1的厨师将是“好”厨师,并且输出应该是具有良好评级数的厨师id

cook_id cook_rating
1       7
然而,id为2的厨师不符合我的条件,因此根本不应该被列入名单

select cook_id, count(cook_rating) - sum(case when cook_rating = 4 OR cook_rating = 5 then 1 else 0 end) as numberOfGoodRatings from cook
where cook_rating in (1,2,3,4,5)
group by cook_id
order by numberOfGoodRatings desc

然而,这并没有考虑到一个事实,即可能有超过4或5个好的评级,从而导致负输出。另外,至少70%的要求不包括在内。

我建议您稍微更改您的模式,使此类查询变得简单

假设您在cook表中添加了5列,只需计算每个等级的数量:

nb_ratings_1 nb_ratings_2 nb_ratings_3 nb_ratings_4 nb_ratings_5 

在DB中输入新的评级时更新这样一个表是微不足道的,就像在冗余让您感到紧张时重新计算这些数字一样。它使所有的过滤和排序变得快速和简单。

我建议您稍微更改一下模式,使这种查询变得简单

假设您在cook表中添加了5列,只需计算每个等级的数量:

nb_ratings_1 nb_ratings_2 nb_ratings_3 nb_ratings_4 nb_ratings_5 

在DB中输入新的评级时更新这样一个表是微不足道的,就像在冗余让您感到紧张时重新计算这些数字一样。它使所有的筛选和排序变得快速和简单。

您可以通过HAVING子句中的比较来获得这一点。如果结果集中必须只有两列,则可以将其包装为子选择
select cook\u id,positive\u ratings FROM(…)

选择
库克,
计数(cook_评级<4或cook_评级为空)为正评级,
将(*)算作总评分
来自库克
按cook_id分组
具有(正评分/总评分)>=0.70
按正额定值说明排序

编辑注意,计数(cook_评级<4)仅用于计数评级小于4的行。MySQL文档说count只计算非空行。我还没有测试过它是否等于FALSE和NULL,但我很惊讶它不是。最坏情况下,我们需要将其包装在一个
IF(cook_rating<4,1,NULL)

中,您可以通过HAVING子句中的比较得到这一点。如果结果集中必须只有两列,则可以将其包装为子选择
select cook\u id,positive\u ratings FROM(…)

选择
库克,
计数(cook_评级<4或cook_评级为空)为正评级,
将(*)算作总评分
来自库克
按cook_id分组
具有(正评分/总评分)>=0.70
按正额定值说明排序


编辑注意,计数(cook_评级<4)仅用于计数评级小于4的行。MySQL文档说count只计算非空行。我还没有测试过它是否等于FALSE和NULL,但我很惊讶它不是。最坏的情况下,我们需要将其包装在一个
IF(cook_rating<4,1,NULL)

我相信您会对.Nice文章的解决方案感兴趣,但对于我的需求来说太复杂了。在我的例子中,我只想对有用评级的数量进行排序,如果这个人有超过70%的好评级。因此,即使这不是给某人评级的好方法,但10个好评级和0个坏评级的人仍然比1000个好评级和300个负面评级的人“价值低”。我相信你会对。不错的文章的解决方案感兴趣,但对我的需要来说太复杂了。在我的例子中,我只想对有用评级的数量进行排序,如果这个人有超过70%的好评级。因此,一个人有10个好的评分,0个坏的评分,仍然比一个人有1000个好的评分,但有300个坏的评分“价值低”,即使这不是一个好的评分方式。这不是一个标准化的模式!我假设问题中的表格是“分级事件”,每个都对应一个厨师的用户分级,在这种情况下,将每个事件作为一行是非常有价值的。此外,当您修改系统以支持1到10之间的评级时,会发生什么情况?更改您的模式?当然,这不会阻止单独保存每个评级(这就是我提到冗余的原因)。是的,这意味着如果你改变了问题,你可以添加列。数据库必须实用且快速,以提供所需的有用结果。这种传播结构的目标是允许快速计算大多数类型的评级/排序。这不是一个规范化的模式!我假设问题中的表格是“分级事件”,每个都对应一个厨师的用户分级,在这种情况下,将每个事件作为一行是非常有价值的。此外,当您修改系统以支持1到10之间的评级时,会发生什么情况?更改您的模式?当然,这不会阻止单独保存每个评级(这就是我提到冗余的原因)。是的,这意味着如果你改变了问题,你可以添加列。数据库必须实用且快速,以提供所需的有用结果。这种传播结构的目标是允许快速计算大多数类型的评级/排序。我只是想问,如果cook_评级为空,会发生什么。回家后,我会尝试这个查询。我可能会使用
coalesce
,而不是
if
。如果评级为空,它将根本不参与结果,因为它不会与正的评级计数()或总评级计数()匹配。您可以通过添加cook_评级不为空的
来确保这一点
@TerryUhlang如果评级为空,您想做什么?忘了提及。无评级等于正评级。还修改了总评级计数()以与之匹配(*