连续 streaks/non-streaks 基于按球队分组的胜、平和负
Consecutive streaks/non-streaks based on Win, Draw & Loss grouped by team
我正在尝试根据输赢和平局标准计算结果数据库中的连胜数。
目标:获得 wins/non-wins 的最长连胜纪录(按球队
分组)
我尝试了来自其他线程的不同 SQL 查询建议,但我要么遗漏了分组列,要么遗漏了团队列,并且通常只采用 2 向选项(输赢)- 我需要 3-方式选项(赢、输、平局,包括非赢、非输和非平局)
看了这个 - https://www.sqlteam.com/articles/detecting-runs-or-streaks-in-your-data
但我不知道如何让团队包括。组合成组合
方案:
CREATE TABLE teamresults (matchid varchar(255), date DATE, time TIME, team varchar(255), teamresult varchar(255))
数据样本:
INSERT INTO teamresults (matchid,"date","time",team,teamresult) VALUES
('030420181800acfc','2018-04-03','18:00:00','AC Horsens','L')
,('080420181600brac','2018-04-08','16:00:00','AC Horsens','L')
,('150420181400aaac','2018-04-15','14:00:00','AC Horsens','L')
,('180420181800acfc','2018-04-18','18:00:00','AC Horsens','D')
,('210420181600fcac','2018-04-21','16:00:00','AC Horsens','L')
,('270420181900acfc','2018-04-27','19:00:00','AC Horsens','L')
,('040520181900acaa','2018-05-04','19:00:00','AC Horsens','W')
,('110520181900fcac','2018-05-11','19:00:00','AC Horsens','L')
,('180520182000acbr','2018-05-18','20:00:00','AC Horsens','D')
,('210520181800fcac','2018-05-21','18:00:00','AC Horsens','L')
,('120520191200veac','2019-05-12','12:00:00','AC Horsens','W')
,('190520191400acve','2019-05-19','14:00:00','AC Horsens','D')
,('140720191400acfc','2019-07-14','14:00:00','AC Horsens','L')
,('210720191200siac','2019-07-21','12:00:00','AC Horsens','W')
,('270720191730acfc','2019-07-27','17:30:00','AC Horsens','L')
,('040820191600brac','2019-08-04','16:00:00','AC Horsens','W')
,('010420181400hoag','2018-04-01','14:00:00','AGF','W')
,('080420181800agsi','2018-04-08','18:00:00','AGF','W')
,('130420181900agfc','2018-04-13','19:00:00','AGF','W')
,('170420181900fcag','2018-04-17','19:00:00','AGF','L')
,('230420181900agho','2018-04-23','19:00:00','AGF','L')
,('300420181900siag','2018-04-30','19:00:00','AGF','W')
,('060520181200agob','2018-05-06','12:00:00','AGF','W')
,('130520181800obag','2018-05-13','18:00:00','AGF','W')
,('190520181600ags�','2018-05-19','16:00:00','AGF','D')
;
下面的查询确实有效,但只执行单个输入语句 - 所以我只能获得连续获胜、失败或平局 - 而不是非胜利、非损失和非平局。
SELECT
team,
MAX(cnt)
FROM
(
SELECT
team,
COUNT(*) AS cnt
FROM
(
SELECT
team,
date,
teamresult,
SUM(CASE WHEN teamresult <> 'W' THEN 1 else 0 END)
OVER (PARTITION BY team
ORDER BY date
ROWS UNBOUNDED PRECEDING) AS dummy
FROM teamresults
) dt
WHERE teamresult = 'W'
GROUP BY team, dummy
) dt
GROUP BY team;
我还希望能够找到按团队分组的最长非连胜纪录
SQL fiddle 可在此处获得:
http://sqlfiddle.com/#!18/3a2ac/1
提前致谢
更新:
Gordon 查询正在运行,但这些查询在 postgres/cockroach 中不起作用 - 所以现在尝试通过 window 函数 rank()
将它们转换为支持的查询
select team, teamresult, cnt, rank() over (order by cnt desc) from
(SELECT team, teamresult, COUNT(*) as cnt
FROM (SELECT tr.*,
ROW_NUMBER() OVER (PARTITION BY team ORDER BY "date", "time") as seqnum,
ROW_NUMBER() OVER (PARTITION BY team, teamresult ORDER BY "date", "time") as seqnum_r
FROM teamresults tr
) tr
WHERE teamresult = 'W'
GROUP BY team, teamresult, (seqnum - seqnum_r)
ORDER BY ROW_NUMBER() OVER (PARTITION BY team ORDER BY COUNT(*) DESC)) as ranked
这确实给了我这样的输出(来自我的数据库的数据样本):
FC København W 9 1
AaB W 8 2
FC København W 8 2
FC København W 8 2
FC København W 8 2
Brøndby IF W 7 6
FC Midtjylland W 7 6
FC København W 7 6
FC København W 7 6
FC København W 7 6
Esbjerg fB W 6 11
FC Midtjylland W 6 11
AaB W 6 11
Brøndby IF W 6 11
Brøndby IF W 6 11
预期输出:
Team Longest consecutive streak
FC København 9
AaB 8
Brøndby IF 7
FC Midtjylland 7
Esbjerg fB 6
您可以使用以下方法获得所有条纹:
SELECT team, teamresult, COUNT(*) as cnt
FROM (SELECT tr.*,
ROW_NUMBER() OVER (PARTITION BY team ORDER BY "date", "time") as seqnum,
ROW_NUMBER() OVER (PARTITION BY team, teamresult ORDER BY "date", "time") as seqnum_r
FROM teamresults tr
) tr
GROUP BY team, teamresult, (seqnum - seqnum_r);
您可以修改这个以获得每支球队最长的连胜纪录:
SELECT TOP(1) WITH TIES team, teamresult, COUNT(*) as cnt
FROM (SELECT tr.*,
ROW_NUMBER() OVER (PARTITION BY team ORDER BY "date", "time") as seqnum,
ROW_NUMBER() OVER (PARTITION BY team, teamresult ORDER BY "date", "time") as seqnum_r
FROM teamresults tr
) tr
WHERE teamresult = 'W'
GROUP BY team, teamresult, (seqnum - seqnum_r)
ORDER BY ROW_NUMBER() OVER (PARTITION BY team ORDER BY COUNT(*) DESC);
如果您只想要任何类型的最长连胜,请删除 WHERE
。如果您希望每个团队的每种类型最长,则将 teamresult
添加到 PARTITION BY
。
Here 是一个 db<>fiddle.
编辑:
如果要非赢,需要按表达式进行分区:
SELECT TOP(1) WITH TIES team,
(CASE WHEN teamresult = 'W' THEN 'W' END) as is_win,
COUNT(*) as cnt
FROM (SELECT tr.*,
ROW_NUMBER() OVER (PARTITION BY team ORDER BY "date", "time") as seqnum,
ROW_NUMBER() OVER (PARTITION BY team, (CASE WHEN teamresult = 'W' THEN 'W' END) ORDER BY "date", "time") as seqnum_r
FROM teamresults tr
) tr
-- WHERE teamresult = 'W'
GROUP BY team, (CASE WHEN teamresult = 'W' THEN 'W' END), (seqnum - seqnum_r)
ORDER BY ROW_NUMBER() OVER (PARTITION BY team ORDER BY COUNT(*) DESC)
感谢 Gordon,我通过以下查询解决了我的问题:
最长连续连胜(平局用 D 代替,负用 L 代替)按球队分组
select team, max(cnt) longeststreak from (
SELECT team, teamresult, COUNT(*) as cnt
FROM (SELECT tr.*,
RANK() OVER (PARTITION BY team ORDER BY "date", "time") as seqnum,
RANK() OVER (PARTITION BY team, teamresult ORDER BY "date", "time") as seqnum_r
FROM teamresults tr
) tr
WHERE teamresult = 'W'
GROUP BY team, teamresult, (seqnum - seqnum_r)
ORDER BY RANK() OVER (PARTITION BY team ORDER BY COUNT(*) DESC)
)
group by team
order by longeststreak DESC
最长的连续不赢(用D代替W表示不平局,用L代替不输)按球队分组
select team, max(cnt) longestnonstreak from (
SELECT team,
(CASE WHEN teamresult = 'W' THEN 'W' END) as is_win,
COUNT(*) as cnt
FROM (SELECT tr.*,
RANK() OVER (PARTITION BY team ORDER BY "date", "time") as seqnum,
RANK() OVER (PARTITION BY team, (CASE WHEN teamresult = 'W' THEN 'W' END) ORDER BY "date", "time") as seqnum_r
FROM teamresults tr
) tr
GROUP BY team, (CASE WHEN teamresult = 'W' THEN 'W' END), (seqnum - seqnum_r)
ORDER BY RANK() OVER (PARTITION BY team ORDER BY COUNT(*) DESC)
)
group by team
order by longestnonstreak desc
感谢 Gordon 协助解决。
我正在尝试根据输赢和平局标准计算结果数据库中的连胜数。
目标:获得 wins/non-wins 的最长连胜纪录(按球队
分组)我尝试了来自其他线程的不同 SQL 查询建议,但我要么遗漏了分组列,要么遗漏了团队列,并且通常只采用 2 向选项(输赢)- 我需要 3-方式选项(赢、输、平局,包括非赢、非输和非平局)
看了这个 - https://www.sqlteam.com/articles/detecting-runs-or-streaks-in-your-data
但我不知道如何让团队包括。组合成组合
方案:
CREATE TABLE teamresults (matchid varchar(255), date DATE, time TIME, team varchar(255), teamresult varchar(255))
数据样本:
INSERT INTO teamresults (matchid,"date","time",team,teamresult) VALUES
('030420181800acfc','2018-04-03','18:00:00','AC Horsens','L')
,('080420181600brac','2018-04-08','16:00:00','AC Horsens','L')
,('150420181400aaac','2018-04-15','14:00:00','AC Horsens','L')
,('180420181800acfc','2018-04-18','18:00:00','AC Horsens','D')
,('210420181600fcac','2018-04-21','16:00:00','AC Horsens','L')
,('270420181900acfc','2018-04-27','19:00:00','AC Horsens','L')
,('040520181900acaa','2018-05-04','19:00:00','AC Horsens','W')
,('110520181900fcac','2018-05-11','19:00:00','AC Horsens','L')
,('180520182000acbr','2018-05-18','20:00:00','AC Horsens','D')
,('210520181800fcac','2018-05-21','18:00:00','AC Horsens','L')
,('120520191200veac','2019-05-12','12:00:00','AC Horsens','W')
,('190520191400acve','2019-05-19','14:00:00','AC Horsens','D')
,('140720191400acfc','2019-07-14','14:00:00','AC Horsens','L')
,('210720191200siac','2019-07-21','12:00:00','AC Horsens','W')
,('270720191730acfc','2019-07-27','17:30:00','AC Horsens','L')
,('040820191600brac','2019-08-04','16:00:00','AC Horsens','W')
,('010420181400hoag','2018-04-01','14:00:00','AGF','W')
,('080420181800agsi','2018-04-08','18:00:00','AGF','W')
,('130420181900agfc','2018-04-13','19:00:00','AGF','W')
,('170420181900fcag','2018-04-17','19:00:00','AGF','L')
,('230420181900agho','2018-04-23','19:00:00','AGF','L')
,('300420181900siag','2018-04-30','19:00:00','AGF','W')
,('060520181200agob','2018-05-06','12:00:00','AGF','W')
,('130520181800obag','2018-05-13','18:00:00','AGF','W')
,('190520181600ags�','2018-05-19','16:00:00','AGF','D')
;
下面的查询确实有效,但只执行单个输入语句 - 所以我只能获得连续获胜、失败或平局 - 而不是非胜利、非损失和非平局。
SELECT
team,
MAX(cnt)
FROM
(
SELECT
team,
COUNT(*) AS cnt
FROM
(
SELECT
team,
date,
teamresult,
SUM(CASE WHEN teamresult <> 'W' THEN 1 else 0 END)
OVER (PARTITION BY team
ORDER BY date
ROWS UNBOUNDED PRECEDING) AS dummy
FROM teamresults
) dt
WHERE teamresult = 'W'
GROUP BY team, dummy
) dt
GROUP BY team;
我还希望能够找到按团队分组的最长非连胜纪录
SQL fiddle 可在此处获得: http://sqlfiddle.com/#!18/3a2ac/1
提前致谢
更新: Gordon 查询正在运行,但这些查询在 postgres/cockroach 中不起作用 - 所以现在尝试通过 window 函数 rank()
将它们转换为支持的查询select team, teamresult, cnt, rank() over (order by cnt desc) from
(SELECT team, teamresult, COUNT(*) as cnt
FROM (SELECT tr.*,
ROW_NUMBER() OVER (PARTITION BY team ORDER BY "date", "time") as seqnum,
ROW_NUMBER() OVER (PARTITION BY team, teamresult ORDER BY "date", "time") as seqnum_r
FROM teamresults tr
) tr
WHERE teamresult = 'W'
GROUP BY team, teamresult, (seqnum - seqnum_r)
ORDER BY ROW_NUMBER() OVER (PARTITION BY team ORDER BY COUNT(*) DESC)) as ranked
这确实给了我这样的输出(来自我的数据库的数据样本):
FC København W 9 1
AaB W 8 2
FC København W 8 2
FC København W 8 2
FC København W 8 2
Brøndby IF W 7 6
FC Midtjylland W 7 6
FC København W 7 6
FC København W 7 6
FC København W 7 6
Esbjerg fB W 6 11
FC Midtjylland W 6 11
AaB W 6 11
Brøndby IF W 6 11
Brøndby IF W 6 11
预期输出:
Team Longest consecutive streak
FC København 9
AaB 8
Brøndby IF 7
FC Midtjylland 7
Esbjerg fB 6
您可以使用以下方法获得所有条纹:
SELECT team, teamresult, COUNT(*) as cnt
FROM (SELECT tr.*,
ROW_NUMBER() OVER (PARTITION BY team ORDER BY "date", "time") as seqnum,
ROW_NUMBER() OVER (PARTITION BY team, teamresult ORDER BY "date", "time") as seqnum_r
FROM teamresults tr
) tr
GROUP BY team, teamresult, (seqnum - seqnum_r);
您可以修改这个以获得每支球队最长的连胜纪录:
SELECT TOP(1) WITH TIES team, teamresult, COUNT(*) as cnt
FROM (SELECT tr.*,
ROW_NUMBER() OVER (PARTITION BY team ORDER BY "date", "time") as seqnum,
ROW_NUMBER() OVER (PARTITION BY team, teamresult ORDER BY "date", "time") as seqnum_r
FROM teamresults tr
) tr
WHERE teamresult = 'W'
GROUP BY team, teamresult, (seqnum - seqnum_r)
ORDER BY ROW_NUMBER() OVER (PARTITION BY team ORDER BY COUNT(*) DESC);
如果您只想要任何类型的最长连胜,请删除 WHERE
。如果您希望每个团队的每种类型最长,则将 teamresult
添加到 PARTITION BY
。
Here 是一个 db<>fiddle.
编辑:
如果要非赢,需要按表达式进行分区:
SELECT TOP(1) WITH TIES team,
(CASE WHEN teamresult = 'W' THEN 'W' END) as is_win,
COUNT(*) as cnt
FROM (SELECT tr.*,
ROW_NUMBER() OVER (PARTITION BY team ORDER BY "date", "time") as seqnum,
ROW_NUMBER() OVER (PARTITION BY team, (CASE WHEN teamresult = 'W' THEN 'W' END) ORDER BY "date", "time") as seqnum_r
FROM teamresults tr
) tr
-- WHERE teamresult = 'W'
GROUP BY team, (CASE WHEN teamresult = 'W' THEN 'W' END), (seqnum - seqnum_r)
ORDER BY ROW_NUMBER() OVER (PARTITION BY team ORDER BY COUNT(*) DESC)
感谢 Gordon,我通过以下查询解决了我的问题:
最长连续连胜(平局用 D 代替,负用 L 代替)按球队分组
select team, max(cnt) longeststreak from (
SELECT team, teamresult, COUNT(*) as cnt
FROM (SELECT tr.*,
RANK() OVER (PARTITION BY team ORDER BY "date", "time") as seqnum,
RANK() OVER (PARTITION BY team, teamresult ORDER BY "date", "time") as seqnum_r
FROM teamresults tr
) tr
WHERE teamresult = 'W'
GROUP BY team, teamresult, (seqnum - seqnum_r)
ORDER BY RANK() OVER (PARTITION BY team ORDER BY COUNT(*) DESC)
)
group by team
order by longeststreak DESC
最长的连续不赢(用D代替W表示不平局,用L代替不输)按球队分组
select team, max(cnt) longestnonstreak from (
SELECT team,
(CASE WHEN teamresult = 'W' THEN 'W' END) as is_win,
COUNT(*) as cnt
FROM (SELECT tr.*,
RANK() OVER (PARTITION BY team ORDER BY "date", "time") as seqnum,
RANK() OVER (PARTITION BY team, (CASE WHEN teamresult = 'W' THEN 'W' END) ORDER BY "date", "time") as seqnum_r
FROM teamresults tr
) tr
GROUP BY team, (CASE WHEN teamresult = 'W' THEN 'W' END), (seqnum - seqnum_r)
ORDER BY RANK() OVER (PARTITION BY team ORDER BY COUNT(*) DESC)
)
group by team
order by longestnonstreak desc
感谢 Gordon 协助解决。