0

我有一个正确回答这个问题的查询:平均评分最高的电影的名称是什么?

select title 
from (
   select movies.title, avg(rating) avgrating 
   from movies, rentals 
   where movies.movieid = rentals.movieid 
   group by movies.title
) a 
where avgrating = (select max(avgrating) 
                   from (select movies.title, avg(rating) avgrating 
                   from movies, rentals 
                   where movies.movieid=rentals.movieid 
                   group by movies.title) b) 
order by title desc

唯一的问题是在我的大型数据库上运行需要几分钟。我想不出如何让它更快。基本上子查询 a 和 b 是等价的,但据我所知,我必须重复一遍,因为 where 子句看不到“a”子查询。重要提示:最高平均评分可能会出现平局,并且查询必须返回与平局中的标题一样多的标题。 我还应该提到,连接是必要的,因为标题在电影表中,而评级在租借表中。

Movies (
    movieId INTEGER PRIMARY KEY,
    title TEXT,
    year INTEGER
)

Rentals (
    cardNo INTEGER,
    movieId INTEGER,
    date DATE,
    rating INTEGER,
    PRIMARY KEY(cardNo, movieID, date),
    FOREIGN KEY (cardNo) REFERENCES Customers,
    FOREIGN KEY (movieId) REFERENCES Movies
)
4

1 回答 1

1

您可以使用公用表表达式仅运行一次子查询:

with avg_ratings as (
   select movies.title, 
          avg(rentals.rating) as avgrating 
   from movies
     join rentals on movies.movieid = rentals.movieid 
   group by movies.title
)    
select title 
from avg_ratings 
where avgrating = (select max(avgrating) from avg_ratings);

这也可以使用窗口函数来编写:

with avg_ratings as (
   select movies.title, 
          avg(rentals.rating) as avgrating 
   from movies
     join rentals on movies.movieid = rentals.movieid 
   group by movies.title
)    
select title
from (
   select title, 
          avgrating,
          dense_rank() over (order by avgrating desc) as rating_rank
   from avg_ratings
) t
where rating_rank = 1;

不确定哪个版本更快。


如果仍然存在性能问题,则需要发布表的定义、它们的索引和执行计划(有关如何发布与性能相关的问题的更多信息,请参见此处:http ://wiki.postgresql.org/wiki/慢查询问题

于 2013-10-01T07:48:26.230 回答