我有那些桌子
table1: GROUPS
grpID | name
--------------
1 | A
2 | B
3 | C
4 | D
5 | E
table2: USERS
userID | grpID | name
----------------------
1 |1 | nick
2 |1 | john
3 |1 | florans
4 |1 | keit
5 |1 | maria
6 |2 | ian
7 |2 | george
8 |2 | peter
9 |2 | bill
10 |2 | jonathan
11 |3 | jenifer
12 |3 | mina
13 |3 | ben
14 |3 | nick
15 |3 | john
16 |4 | florans
17 |4 | keit
18 |4 | maria
19 |4 | ian
20 |4 | george
21 |5 | peter
22 |5 | bill
23 |5 | jonathan
24 |5 | jenifer
25 |5 | mina
table3:POSTS
userID | posts
--------------
1 | 14
2 | 65
3 | 3
4 | 65
5 | 98
6 | 37
7 | 81
8 | 13
9 | 22
10 | 74
11 | 88
12 | 31
13 | 37
14 | 64
15 | 1
16 | 76
17 | 50
18 | 39
19 | 69
20 | 42
21 | 17
22 | 56
23 | 89
24 | 53
25 | 20
我的目标是获得每组中前3行的AVG(平均值)。 (或(max1,max2,max3)/ 3的SUM)。 像这样:
grpID | max1 | max2 | max3 | AVG of max1, max2, max3
---------------------------------------------------------
1 98 65 65 76
5 89 56 53 66
4 76 69 50 65
2 81 74 37 64
3 88 64 37 63
并显示ORDER BY前3个平均DESC。
最终结果如下:
grpID | first 3 higher rows Average
---------------------------------
1 |76
5 |66
4 |65
2 |64
3 |63
我尝试了什么:(***编辑草莓评论后)
SELECT GROUPS.grpID, GROUPS.name, AVG(POSTS.posts) AS PostsAVG
FROM USERS
INNER JOIN POSTS ON POSTS.userID = USERS.userID
INNER JOIN GROUPS ON GROUPS.grpID = USERS.grpID
GROUP BY GROUPS.grpID
ORDER BY PostsAVG DESC
我得到的结果是
grpID | name | PostsAVG
--------------------------------
4 | D | 55.2000
1 | A | 49.0000
5 | E | 47.0000
2 | B | 45.4000
3 | C | 44.2000
我怎样才能获得前三行而不是全部5行平均值? 任何人都可以帮忙解决这个问题吗?
答案 0 :(得分:0)
您可以使用变量按照每组下降帖子的顺序对记录进行编号。然后,您可以过滤那些行号(< 4
)上的那些,以最终平均每组:
select grpid, avg(posts) as postavg
from ( select @rn := if(@grpid = grpid, @rn+1, 1) as rn,
@grpid := grpid as grpid,
posts
from ( select grpid, posts
from users1
inner join posts1
on posts1.userid = users1.userid
order by grpid, posts desc
) ordered,
( select @grpid := 0, @rn := 1) init
) numbered
where rn < 4
group by grpid;
没有变量(并且没有窗口函数的可用性),你可能最好为此创建一个函数:
create function GetAveragePosts (grpid int)
returns float
return (select avg(posts)
from ( select posts
from users
inner join posts
on posts.userid = users.userid
where users.grpid = grpid
order by posts desc
limit 3
) topthree
);
然后SQL本身很简单:
select grpid,
GetAveragePosts(grpid) as postsavg
from users
group by grpid
order by 2 desc
MySql fiddle输出:
| grpID | postsavg |
|-------|----------|
| 1 | 76 |
| 5 | 66 |
| 4 | 65 |
| 2 | 64 |
| 3 | 63 |