SQL Group通过使用每个组中的前N个元素

时间:2013-04-21 03:26:19

标签: mysql sql linq group-by average

假设我有下一张桌子:

+------------+---------+
|    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   |
+------------+---------+

我想通过组BUT使用每组的前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   |
+------------+---------+

这是我必须为所有电影获取AVG的SQL查询。但正如我所说,我想只使用每组的前2个元素。

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

如果你能帮助我做出我欣赏的SQL。我也会使用Linq以防你们有些人知道。

3 个答案:

答案 0 :(得分:0)

在SQL DBMS中 - 就像在关系模型中一样 - 没有“第一”。你的意思是每部电影有任意2行,还是两个最高等级,还是其他什么?

如果您无法定义订单,那么查询就毫无意义。

如果您可以定义订单,请在我canonical example中显示以创建排名时将表格连接到自身,然后选择where RANK < 3

答案 1 :(得分:0)

FOR 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;

你可以在oracle中使用rownum函数。并且row_number()在sql server中运行。

答案 2 :(得分:-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