【问题标题】:Query to extract top records by average grade and name查询以按平均成绩和姓名提取最高记录
【发布时间】:2017-11-13 21:14:10
【问题描述】:

我有两张桌子:MoviesReviews

Movies 具有以下列:ID、Title、Genre、Duration;

Reviews 具有 ID、描述、Movie_ID(引用电影的 ID)和等级。

我想按平均值显示电影的顶部。 (我想显示电影的标题以及它的平均成绩。)

我尝试了 2 个子查询:一个选择标题,一个从评论中获取 AVG(与电影一起),但我不知道如何将 SELECT AVG(GRADE)... 的结果提供给 SELECT TITLE FROM MOVIES ...。 我在尝试正确的方法吗?

Movies

ID        TITLE          GENRE       DURATION
1         Movie_name_1   Sci-fi      120
2         Movie_name_2   Comedy      100
3         Movie_name_3   Drama       140
4         Movie_name_4   Sci-fi      105

Reviews
ID        Description    Movie_id      Grade 
1         WOW             1             10
2         SUCH            2             9
3         Great           3             9
4         Amazing         2             10
5         Decent          4             7
6         Legendary       2             10
7         Waste           3             4
8         hmmm            1             6

预期结果:

Movie_name_1           9.50
Movie_name_2           9.25
Movie_name_3           8.25
Movie_name_4           7

【问题讨论】:

  • 您使用的是哪个DBMS 产品?后格雷斯?甲骨文? “SQL”只是一种查询语言,并不是特定数据库产品的名称。
  • Edit您的问题并添加一些sample data 和基于该数据的预期输出。 Formatted textno screen shotsedit 您的问题 - 请不要在 cmets 中提供邮政编码或其他信息。
  • 这似乎是一个简单的INNER JOINgroup byavg() 聚合。你试过什么,什么不起作用?不,我不会有两个查询。现在我看不出您的预期结果如何与您对 movie_name_1 的 10+6 = 16/2 =8 的数据相匹配,但您有 9.5...
  • 我不知道我可以在与电影标题相同的选择中从评论中选择评分的 AVG,这让我感到困惑。 (提供的数据只是一个示例,以明确范围,不适合实际平均值)

标签: sql oracle oracle-sqldeveloper


【解决方案1】:

这应该可以,只需将FETCH 数字更改为您想查看的行数即可:

SELECT Title, AVG(Grade) Grade
FROM Movies M
JOIN Reviews R on R.Movie_ID = M.ID
GROUP BY Title
ORDER BY Grade DESC
FETCH FIRST 5 ROWS ONLY;

编辑:下面有更详细的解释

这个查询的依据是:

SELECT Title, Grade
FROM Movies M
JOIN Reviews R on R.Movie_ID = M.ID

这会在一个结果集中为您提供所需的所有信息。

接下来,您需要每部电影的平均 Grade Title

这是通过使用平均函数 AVG() 并按 Title 分组来完成的(因为您毕竟想要每个标题的平均成绩):

SELECT Title, AVG(Grade) Grade
FROM Movies M
JOIN Reviews R on R.Movie_ID = M.ID
GROUP BY Title

注意:AVG(Grade) Grade 中的第二个 Grade 只是一个别名。 AVG(Grade) 没有列名,因此为简单起见,我们将新的平均列称为Grade

你也可以写成AVG(Grade) as Grade,这对你来说可能更清楚。

接下来,您想先看最受欢迎的电影。我们使用ORDER BY 来做到这一点。我们可以在这里参考我们的平均Grade 列:

SELECT Title, AVG(Grade) Grade
FROM Movies M
JOIN Reviews R on R.Movie_ID = M.ID
GROUP BY Title
ORDER BY Grade DESC --Referencing the averaged column, not the main column

最后但并非最不重要的一点是,您提到要查看前 n 行。我们可以使用FETCH FIRST n ROWS ONLY 子句来做到这一点:

SELECT Title, AVG(Grade) Grade
FROM Movies M
JOIN Reviews R on R.Movie_ID = M.ID
GROUP BY Title
ORDER BY Grade DESC
FETCH FIRST 5 ROWS ONLY;

为了更加清晰,这是最后一个版本,别名不同:

SELECT Title, AVG(Grade) Averaged_Grade
FROM Movies M
JOIN Reviews R on R.Movie_ID = M.ID
GROUP BY Title
ORDER BY Averaged_Grade DESC
FETCH FIRST 5 ROWS ONLY;

【讨论】:

  • 谢谢!这解决了我的问题!你能解释一下AVG(Grade) Grade 语法在那里的工作原理吗?我对这个查询的困惑是,我不知道我可以在同一个 Select 语句中同时从电影中选择标题和从评论中选择平均成绩,我试图将它们分成 2 个选择。
  • @Daniel 当然。让我编辑一个解释,我将有更多的空间输入
  • @Daniel 查看编辑,可能超出您的需要,但应该以这种方式清楚。如果您随时运行每个查询,那也会有所帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多