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

共通テーブル式を使用して、サブクエリを 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/ SlowQueryQuestions )

于 2013-10-01T07:48:26.230 に答える