0

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

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

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

所以在我的示例表中,id 为 1 的厨师共有 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% 的要求。

4

2 回答 2

3

您可以通过 HAVING 子句中的比较来获得此信息。如果您必须在结果集中只有两列,则可以将其包装为子选择select cook_id, positive_ratings FROM (...)

SELECT 
  cook_id, 
  count(cook_rating < 4 OR cook_rating IS NULL) as positive_ratings, 
  count(*) as total_ratings
FROM cook
GROUP BY cook_id
HAVING (positive_ratings / total_ratings) >= 0.70
ORDER BY positive_ratings DESC

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

于 2012-07-08T16:47:32.773 回答
0

我建议您稍微更改一下您的架构,以使这种查询变得微不足道。

假设您将 5 列添加到您的烹饪表中,以简单地计算每个评分的数量:

nb_ratings_1 nb_ratings_2 nb_ratings_3 nb_ratings_4 nb_ratings_5 

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

于 2012-07-08T16:45:03.247 回答