2014-01-15 7 views
1

Найти фильм (ы) с самым высоким средним рейтингом. Верните название фильма и средний рейтинг.Фильм с самым высоким рейтингом?

Я попытался это и застрял, потому что я не в состоянии получить mid, если я добавить mid, max(avg_stars) то это даст max каждый mid, я хочу только один max значения.

http://sqlfiddle.com/#!3/e3ee1/13

select max(avg_stars) from 
(
select top 1 mid, avg(stars) as avg_stars 
from rating 
group by mid 
order by avg_stars desc 
) z 

освобожденный выход Snow White 4.5 и как я могу справиться, если два фильма, имеющие такой же максимум (avg_stars).

+0

Не знаете, какой контроль у вас есть по делу/делу UI здесь, но я думаю, что с точки зрения удобства использования было бы полезно предоставить пользователям количество рейтингов. Один 5-звездочный обзор, как правило, гораздо менее надежный, чем 100 отзывов, дающих 4 звезды. Немного не по теме, но, на мой взгляд, стоит упомянуть. Возможно, даже если вы получите самый высокий рейтинг, вы получите несколько фильмов с одним рейтингом, которые, возможно, не будут служить исходной цели этого запроса. – Kahn

ответ

0
SELECT TOP 1 MAX(m.title) AS title, AVG(stars) AS averageStars 
FROM rating r 
JOIN movie m 
    ON r.mId = m.mId 
GROUP BY r.mId 
ORDER BY AVG(stars) DESC, 
      --Order by a seond column of your 
      --choice to break ties for AVG(stars) 
     MAX(m.title) 
+0

Разве ваш SELECT TOP 1 не возвращает только одну запись, а не все те, которые соответствуют критерию наличия среднего среднего? –

+0

Да, да. Я не уверен точно, как OP хочет рассмотреть случаи, когда более одного фильма имеет максимальный средний показатель. Поэтому я решил пойти с возвращением точно одного из фильмов с высшим средним. –

+0

Хорошо, это была интересная проблема. :) –

0

Вы, вероятно, можно оптимизировать или придумать что-то более чистого, но это работает:

SELECT m.title, AVG(r.stars) AS AverageStars 
FROM  Rating AS r (NOLOCK) 
INNER JOIN Movie AS m (NOLOCK) ON m.mID = r.mID 
GROUP BY r.mID, m.Title 
HAVING AVG(r.stars) = 
(
    SELECT TOP 1 AVG(stars) AS AverageStars 
    FROM Rating (NOLOCK) 
    GROUP BY mID 
    ORDER BY AverageStars DESC 
) 
+0

Подзапрос в условии WHERE '(SELECT MAX (stars) FROM Rating)' будет вычисляться каждый раз для каждой строки. Это неправильно. – DoNotArrestMe

+0

Я перечитываю и OP также запрашивает тех, у кого max * average *. Я читал это как те, у кого макс, поэтому я тоже дал неверный ответ. Извиняюсь. Будет отправлен исправленный ответ. –

+0

@NeilCresswell Я хочу, чтобы звезд не было ни одного avg. –

1

Попробуйте http://sqlfiddle.com/#!3/e3ee1/143:

;WITH CTE as 
(
select r.mid, avg(r.stars) as avg_stars, m.title 
from rating r 
INNER JOIN Movie m ON m.mid=r.mid 
group by r.mid, m.title 
--order by avg_stars desc 
) 
select TOP 1 mid, title,avg_stars from CTE 
Group by avg_stars,mid,title 
--having avg_stars=Max(avg_stars) 
Order By avg_stars desc 

Выход:

MID TITLE   AVG_STARS 
    106 Snow White 4.5 
2

Это было служить вашей цели perfectl у & с производительностью -

SELECT 
    Title 
    ,AVG_RATING 
FROM 
(
    SELECT 
     M.Title 
     ,M.mID 
     ,CAST(ROUND(AVG(R.stars),2) AS DECIMAL(10,2)) AS AVG_RATING 
     ,RANK() OVER (ORDER BY AVG(R.stars) DESC) RATING_RANK 
    FROM Movie M 
    INNER JOIN Rating R 
     ON M.mID = R.mID 
    GROUP BY M.Title,M.mID 
)RANKED_RATING 
WHERE RATING_RANK = 1 

Вы, возможно, придется играть вокруг отливки немного, чтобы удовлетворить ваши определения таблиц.

Примечание - Если у 2 или более фильмов самый высокий средний рейтинг - все будут оцениваться в 1 и все будут выбраны. Если вы все еще хотите только один - вам нужно определить правило, по которому вы хотите быть выбранным.

Смежные вопросы