【问题标题】:How to find the avg of better films rating in MySQL如何在 MySQL 中找到更好电影评分的平均值
【发布时间】:2019-04-19 12:05:50
【问题描述】:

我有一张桌子 电影

id  release_year    category_id rating
1   2015                 1         8
2   2015                 2        8.5
3   2015                 3         9
4   2016                 2        8.2
5   2016                 1        8.4
6   2017                 2         7

我想添加一个新列“avg_better_films”,以查找其发行年份中所有更好电影的平均评分

输出应该是

id  release_year    category_id rating  avg_better_films
1   2015                1         8          8.75
2   2015                2        8.5           9
3   2015                3         9        Not Available
4   2016                2        8.2          8.4
5   2016                1        8.4       Not Available
6   2017                2         7        Not Available

你可以看到,什么时候电影在上映年份获得了最佳收视率 它会显示“不可用”

你知道如何在 MySQL 中得到这个输出

【问题讨论】:

  • 简单方法:关联子查询。
  • 请不要使用图片;格式化的代码文本更好。我已经回滚到以前的“OK”版本的问题。

标签: mysql sql database


【解决方案1】:

这很棘手,因为您需要将结果输出为字符串,而不是数字。如果任何值是字符串,则都必须是。

我会推荐一个如下所示的相关子查询:

SELECT f.*,
       (SELECT COALESCE(FORMAT(AVG(t2.rating), 2), 'Not Available)
            FROM Films f2
            WHERE f2.rating > f.rating AND 
                  f2.release_year = f.release_year
       ) AS avg_better_films
FROM Films f

注意事项:

  • 表别名应该是表名的缩写。
  • 如果没有行匹配子查询中的WHERE 子句,则AVG() 返回NULL。因此,COALESCE()可以在子查询中。
  • FORMAT() 用于将平均评分转换为字符串。

【讨论】:

    【解决方案2】:
    • 我们可以使用Correlated Subquery 来计算当年“更好电影”的平均评分。
    • 如果特定电影和年份没有更好的电影,子查询将返回 null
    • 然后我们可以使用Coalesce()函数来处理当年没有找到“更好的电影”的情况。
    • 感谢cmets中的@Strawberry,我们需要对子查询的结果做+ 0,以便MySQL将其视为数字

    尝试以下方法:

    SELECT
      t1.id, 
      t1.release_year, 
      t1.category_id, 
      t1.rating, 
      COALESCE(
               (
                SELECT AVG(t2.rating) 
                FROM Films AS t2
                WHERE t2.rating > t1.rating AND  -- higher rating films
                      t2.release_year = t1.release_year -- films from same year
               ) + 0, 
               'Not Available' -- handle null result of subquery
              ) AS avg_better_films
    FROM Films AS t1
    

    SQL 小提琴: http://sqlfiddle.com/#!9/4960ea/3

    【讨论】:

    • 嗨,Madhur,每部电影的“avg_better_films”是评分高于它的电影的平均值。如果有两个更好的电影,它应该计算两个电影的平均值。如果只有一部更好的电影,它应该只显示更好电影的评分。我相信相关子查询是工作方式,但我不知道如何以不同方式计算每部电影的更好平均值
    • @Rlearn 我的查询也是如此。它只为每部电影计算它。如果同一年有更好的电影,则计算平均收视率;否则返回Not Available
    • @Strawberry 谢谢。只是好奇Avg() 函数不应该返回一个数字或null。我在这里错过了什么?
    • @MadhurBhaiya 我不确定我是否遵循。如果您问我为什么添加“+0”,那是因为存在隐式字符串转换(在您的查询中,或者 [更有可能] 在 sqlfiddle 对您的查询的解释中)。加上 +0 无敌性会再次将其重新施放。要了解我的意思,请尝试不带 +0
    • @Strawberry 是的;我尝试不使用 + 0,这就是为什么我很好奇为什么 Avg() 函数的结果被解释为字符串。
    【解决方案3】:

    您可以尝试使用标量子查询

    select *, (select avg(rating) from Films b on a.release_year=b.release_year) as avg_film_Rating
    from Films a
    

    【讨论】:

      猜你喜欢
      • 2021-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-07
      • 1970-01-01
      • 2020-03-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多