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

Mysql 按类别按最近N个以前的条目汇总,mysql,sql,greatest-n-per-group,Mysql,Sql,Greatest N Per Group,我有一个表,我正在尝试聚合最近N个值的值。在MSSQL中,您可以在子查询中引用外部表,但在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/1

我有一个表,我正在尝试聚合最近N个值的值。在MSSQL中,您可以在子查询中引用外部表,但在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
作为一个例子,假设每一场比赛/团队组合,我想平均该团队最近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
我可以通过像这样将表格加入到自己的表格中来获得之前所有游戏的平均值,但我不知道如何将其限制到最近的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;
使现代化 明白了,伙计

小提琴:


@臭名昭著的Pet0让我朝着正确的方向前进,经过几次与它的较量,我得出了一个相当丑陋的答案。准确地显示我在寻找什么。下面是我提出的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;

这将查询的输出限制为2条记录。我需要将进入聚合的记录数限制为2个游戏。如果我对子查询设置限制,我将无法控制日期。在排序和where子句过滤之前,它会进行限制。所以你想要他们在过去两场比赛中得分的平均值?就像在过去两场比赛中,A队的得分是3分和7分,你会希望它说5分吗?他的帅哥,我让他们两个提出了一个疯狂的问题,我刚刚在我的答案中发布了这个问题。过来看。我现在正在做avg检查。如果这是您想要的,请告诉我。啊,用户变量。哦,老兄,我对这个案子的想法变得非常紧张。这看起来很好,但我需要每场比赛的平均成绩,而不仅仅是每支球队的平均成绩。这有意义吗?我会把它打8分,我想如果我研究用户变量,我应该能够忍受。我很感激那个家伙,我想把它作为我个人的知识,所以我仍然在摆弄它。如果你找到解决方案,请告诉我,我也会这么做。这家伙坚持说:
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;