MySQL从组

时间:2017-04-10 12:25:35

标签: mysql

我有那些桌子

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

我的目标是获得每组中前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行平均值? 任何人都可以帮忙解决这个问题吗?

1 个答案:

答案 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;

http://rextester.com/HWR28741

没有变量

没有变量(并且没有窗口函数的可用性),你可能最好为此创建一个函数:

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 |