按类别汇总最近的 N 个先前条目

Aggregate by most recent N previous entries by category

我有一个 table,我正在尝试聚合最近 N 个值的值。在 MSSQL 中,您可以在子查询中引用外部 table,但不能在 mysql 中引用,因此我想找出另一种方法来执行此操作。这是我正在使用的超级简化版本:

gameid, teamid, gamedate, total
===============================
g1, A, 1/1/15, 1
g1, B, 1/1/15, 2
g2, A, 1/2/15, 3
g2, C, 1/2/15, 4
g3, B, 1/3/15, 5
g3, C, 1/3/15, 6
...
...
g5, A, 1/5/15, 7
...
g8, A, 1/8/15, 8
g8, B, 1/8/15, 9

举个例子,假设对于每个 game/team 组合,我想计算球队最近 2 场比赛的平均值。对于前面的例子,输出看起来像这样(有我的一些评论)

gameid, teamid, AVG(total)
==========================
g1, A, NULL  <--- No games before this
g1, B, NULL
g2, A, 1.0   <--- Only one game before this
g2, C, NULL
g3, B, 2.0
g3, C, 4.0
...
g5, A, 2.0   <---- Two games before this
...
g8, A, 5.0   <---- Three games before this, only average last 2

我可以通过像这样将 table 加入自身来获得所有以前游戏的平均值,但我不知道如何将它限制为最近的 N 游戏:

SELECT g.gameid, g.teamid, g.gamedate, AVG(g1.total)
  FROM games g
  JOIN
       (SELECT teamid, gamedate, total
          FROM games) g1 ON g1.teamid = g.teamid
 WHERE g1.gamedate < g.gamedate
 GROUP BY g.gameid
 ORDER BY gameid DESC;

更新

知道了老兄!

Fiddle: http://sqlfiddle.com/#!9/af1f2b/18

SELECT
    teamid,
    avg(total),
    sub_table.lastgame,   
    sub_table.gamedate   
FROM
    (SELECT
            teamid,
            gameid as lastgame,
            total,
            gamedate,
            @rn:=CASE
                WHEN @var_teamid = teamid THEN @rn + 1
                ELSE 1
            END AS rn,
            @var_teamid:=teamid
    FROM
        (SELECT @var_teamid:=NULL, @rn:=NULL) vars, games

    ORDER BY teamid , gamedate DESC
    ) as sub_table WHERE
        rn <= 2 group by teamid order by teamid, gamedate desc

@Notorious Pet0 让我朝着正确的方向前进,经过几次较量之后得出了我(相当丑陋)的答案。 The results 准确显示我正在寻找的内容。这是我想出的SQL:

SELECT gid, tid, gdate, AVG(total)
  FROM (
        SELECT @r := IF(@c = Concat(gid, tid), @r + 1, 1) AS rownum, 
               @c := Concat(gid, tid), 
               prevgames.* 
          FROM (SELECT @c := NULL, @r := 0) AS _init 
          JOIN (
                SELECT gkey.gameid AS gid, 
                       gkey.teamid AS tid, 
                       gkey.gamedate AS gdate, 
                       gprev.* 
                  FROM games AS gkey 
                  LEFT OUTER JOIN games AS gprev 
                    ON (gkey.teamid = gprev.teamid AND gkey.gameid > gprev.gameid) 
                 ORDER BY gid, tid, gamedate DESC) AS prevgames
        ) AS g
WHERE rownum <= 2
GROUP BY gid, tid, gdate;