简体   繁体   English

MySQL从Group获得前3个MAX值的平均值

[英]MySQL get average of first 3 MAX values from Group

I've got those tables 我有那些桌子

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

MySQL Fiddle MySQL小提琴

My goal is to get AVG (average) of the first 3 higher rows from every group. 我的目标是获得每组中前3行的AVG(平均值)。 (or SUM of (max1, max2, max3) / 3 ). (或(max1,max2,max3)/ 3的SUM)。 Something like this: 像这样的东西:

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

and display it ORDER BY first 3 average DESC. 并显示ORDER BY前3个平均DESC。

The final result will be like this: 最终结果将是这样的:

grpID  | first 3 higher rows Average
---------------------------------
1      |76
5      |66
4      |65
2      |64
3      |63

What i tried: (*** edited after Strawberry's comment) 我尝试了什么:(***编辑草莓评论后)

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

The result i am getting with this is 我得到的结果是

grpID  | name | PostsAVG
--------------------------------
4      |  D   | 55.2000
1      |  A   | 49.0000
5      |  E   | 47.0000
2      |  B   | 45.4000
3      |  C   | 44.2000

How can i get only the first three rows and not all 5 rows Average? 我怎样才能获得前三行而不是全部5行平均值? Can anyone help to solve this? 谁能帮忙解决这个问题?

You could make use of variables to number the records in order of descending posts , per group. 您可以使用变量按照每组下降的帖子顺序对记录进行编号。 And then you could filter those on that row number ( < 4 ) to finally average those per group: 然后你可以过滤那些行号( < 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;

http://rextester.com/HWR28741 http://rextester.com/HWR28741

Without variables 没有变数

Without variables (and without the availability of window functions), you'd probably do best to create a function for this: 没有变量(并且没有窗口函数的可用性),您可能最好为此创建一个函数:

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

And then the SQL itself is straightforward: 然后SQL本身很简单:

select      grpid, 
            GetAveragePosts(grpid) as postsavg
from        users
group by    grpid
order by    2 desc

MySql fiddle outputs: MySql小提琴输出:

| grpID | postsavg |
|-------|----------|
|     1 |       76 |
|     5 |       66 |
|     4 |       65 |
|     2 |       64 |
|     3 |       63 |

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM