按类别汇总最近的 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;
我有一个 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;