2013-04-21 2 views
1

Предположим, у меня есть следующая таблица:SQL Group с использованием первых N элементов в каждой группе

+------------+---------+ 
| MovieId | rating | 
+------------+---------+ 
|  1  |  4 | 
|  1  |  3 | 
|  1  |  2 | 
|  1  |  4 | 
|  1  |  5 | 
|  2  |  3 | 
|  2  |  4 | 
|  2  |  2 | 
|  3  |  1 | 
|  3  |  2 | 
|  3  |  3 | 
|  3  |  5 | 
|  4  |  4 | 
|  4  |  2 | 
+------------+---------+ 

Я хотел бы получить среднее по группе, но используя первые 2 элемента по каждой группе.
Пример:

+------------+---------+ 
| MovieId | rating | 
+------------+---------+ 
|  1  |  4 | 
|  1  |  3 | 
|  2  |  3 | 
|  2  |  4 | 
|  3  |  1 | 
|  3  |  2 | 
|  4  |  4 | 
|  4  |  2 | 
+------------+---------+ 

ответ ожидается:

+------------+---------+ 
| MovieId | AVG | 
+------------+---------+ 
|  1  |  3.5 | 
|  2  |  3.5 | 
|  3  |  1.5 | 
|  4  |  3 | 
+------------+---------+ 

Это запрос SQL я должен получить AVG для всех фильмов. Но, как я сказал, я хотел бы использовать только первые 2 элемента для каждой группы.

SELECT movieid, AVG(cast(rating as DECIMAL(10,2))) AS AVG FROM ratings group by movieid

Если вы можете помочь мне сделать SQL я ценю. Я также буду использовать Linq на случай, если некоторые из вас это узнают.

+0

Первые два элемента на основе чего? –

+0

только первые n элементов в каждой группе. – 2013-04-21 03:32:23

ответ

-1

Это решение в SQL

Create table #tempMovie (movieId int ,rating int) 

INSERT INTO #tempMovie 
Select * from table where movieidid=1 Limit 2 
Union all 
Select * from table where movieidid=2 Limit 2 
Union all 
Select * from table where movieidid=3 Limit 2 
Union all 
Select * from table where movieidid=4 Limit 2 

Временная таблица таблица #tempmovie будет содержать данные, как этот

+------------+---------+ 
| MovieId | rating | 
+------------+---------+ 
|  1  |  4 | 
|  1  |  3 | 
|  2  |  3 | 
|  2  |  4 | 
|  3  |  1 | 
|  3  |  2 | 
|  4  |  4 | 
|  4  |  2 | 
+------------+---------+ 

затем применить группу по

Select movieId, AVG(rating) 
from #tempMovie 
Group by movieId 

Drop table #tempmovie 
+0

Да, это одно решение. Но мне нужно было динамически, я буду работать с 2000 фильмами. И взять только первые 2 - один пример, мне нужно будет сделать avg N + 1 ... – 2013-04-21 03:54:16

+0

Его вопрос помечен 'mysql', который не имеет' top'. – Barmar

+0

@Barmar, тогда 'LIMIT' следует использовать –

0

в СУБД SQL - - как в реляционной модели - нет «первого». Вы имеете в виду любые произвольные 2 строки для каждого фильма, или два самых высоких рейтинга, или что-то еще?

Если вы не можете определить заказ, запрос не имеет смысла.

Если вы можете определить заказ, соедините таблицу с собой, как показано в моем canonical example, чтобы создать рейтинг, и выберите where RANK < 3.

+0

Я мог бы быть 2 произвольными элементами. – 2013-04-21 04:15:17

+0

Я боялся этого. Как я уже сказал, запрос имеет значение * no *. –

0

ДЛЯ Mysql: -

select id, avg(rating) 
from (SELECT a.*, @num := @num + 1 rownum, 
     (select count(*) 
     from movies m 
     where m.id<=a.id) last_count, 

     (select count(*) 
     from movies m1 
     where a.id=m1.id) grp_count 
     from movies a, (SELECT @num := 0) d) f 
where grp_count-(last_count-rownum)<=2 
group by id; 

вы можете использовать rownum функцию оракула. И row_number() функция в sql сервере.

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