基于Neo4j的英超赛事Cypher查询求助(附2000-2110赛季CSV数据集)
英超赛事Neo4j Cypher查询需求
我拥有2000-2110赛季英超赛事的CSV数据集,使用Neo4j图数据库,现需编写以下Cypher查询:
- 列出2000年以来所有参加过英超赛事的球队;
- 展示2010年以来利物浦击败曼联的所有比赛;
- 展示2000年以来执法比赛次数最多的前五名裁判及对应场次;
- 展示2020/21赛季所有球队的进球总数和失球总数;
- 2000年以来主场胜率最高的球队是哪支;
- 2020/21赛季输球最多的球队是哪支;
- 2020/21赛季上半场落后但最终获胜的球队有哪些;
- 2000年以来单赛季积分最高的球队是哪支;
- 展示2020/21赛季所有球队的最终联赛排名(基于总积分);
- 哪支球队的不败纪录最长;
我针对问题2和3尝试编写的代码:
问题2代码(利物浦击败曼联的比赛)
MATCH (l:Team)-[:PLAYED_AWAY]->(m:Match)<-[:PLAYED_HOME]-(u:Team) WHERE l.name = '利物浦' AND u.name = '曼联' AND l.ftr > u.ftr AND m.season >= '2010-11' RETURN m.season, l.name, l.ftr, u.name, u.ftr
注:原代码赛季条件写为2000-01,已根据需求修正为2010-11;需确认ftr字段是否为球队全场进球数,若为比赛结果标识(如'A'代表客场赢),则条件需调整为m.ftr = 'A'
问题3代码(执法次数最多的前五裁判)
MATCH (ref:Referee)-[:REFEREED_BY]->(m:Match) WHERE m.datetime >= datetime('2000-08-19T00:00:00Z') WITH ref, count(m) as 执法场次 ORDER BY 执法场次 DESC LIMIT 5 RETURN ref.name as 裁判姓名, 执法场次
注:原代码中count(ref)应改为count(m)以准确统计执法场次
完整查询解决方案
1. 列出2000年以来所有参赛球队
MATCH (t:Team) WHERE EXISTS { MATCH (t)-[:PLAYED_HOME|:PLAYED_AWAY]->(m:Match) WHERE m.season >= '2000-01' } RETURN DISTINCT t.name as 球队名称 ORDER BY t.name
2. 2010年以来利物浦击败曼联的所有比赛
// 覆盖利物浦主客场两种情况 MATCH (liv:Team)-[:PLAYED_HOME]->(m:Match)<-[:PLAYED_AWAY]-(mun:Team) WHERE liv.name = '利物浦' AND mun.name = '曼联' AND m.ftr = 'H' AND m.season >= '2010-11' UNION MATCH (liv:Team)-[:PLAYED_AWAY]->(m:Match)<-[:PLAYED_HOME]-(mun:Team) WHERE liv.name = '利物浦' AND mun.name = '曼联' AND m.ftr = 'A' AND m.season >= '2010-11' RETURN m.season as 赛季, m.date as 比赛日期, liv.name as 获胜队, mun.name as 失利队, m.fthg as 主队进球, m.ftag as 客队进球 ORDER BY m.date DESC
注:假设ftr字段值为'H'(主队胜)、'A'(客队胜)、'D'(平局);fthg为主队全场进球,ftag为客队全场进球
3. 2000年以来执法次数最多的前五裁判
MATCH (ref:Referee)-[:REFEREED_BY]->(m:Match) WHERE m.season >= '2000-01' WITH ref, COUNT(m) as 执法场次 ORDER BY 执法场次 DESC LIMIT 5 RETURN ref.name as 裁判姓名, 执法场次
4. 2020/21赛季各球队进球与失球总数
// 统计主场数据 MATCH (t:Team)-[:PLAYED_HOME]->(m:Match) WHERE m.season = '2020-21' WITH t, SUM(m.fthg) as 主场进球, SUM(m.ftag) as 主场失球 // 统计客场数据 MATCH (t)-[:PLAYED_AWAY]->(m:Match) WHERE m.season = '2020-21' WITH t, 主场进球 + SUM(m.ftag) as 总进球, 主场失球 + SUM(m.fthg) as 总失球 RETURN t.name as 球队名称, 总进球, 总失球 ORDER BY 总进球 DESC
5. 2000年以来主场胜率最高的球队
MATCH (t:Team)-[:PLAYED_HOME]->(m:Match) WHERE m.season >= '2000-01' WITH t, COUNT(m) as 主场总场次, SUM(CASE WHEN m.ftr = 'H' THEN 1 ELSE 0 END) as 主场胜场 WITH t, 主场胜场 * 100.0 / 主场总场次 as 主场胜率 WHERE 主场总场次 >= 10 // 过滤场次过少的球队 ORDER BY 主场胜率 DESC LIMIT 1 RETURN t.name as 球队名称, 主场胜率, 主场胜场, 主场总场次
6. 2020/21赛季输球最多的球队
MATCH (t:Team)-[:PLAYED_HOME]->(m:Match) WHERE m.season = '2020-21' WITH t, SUM(CASE WHEN m.ftr = 'A' THEN 1 ELSE 0 END) as 主场输场 MATCH (t)-[:PLAYED_AWAY]->(m:Match) WHERE m.season = '2020-21' WITH t, 主场输场 + SUM(CASE WHEN m.ftr = 'H' THEN 1 ELSE 0 END) as 总输场 ORDER BY 总输场 DESC LIMIT 1 RETURN t.name as 球队名称, 总输场
7. 2020/21赛季上半场落后最终获胜的球队
// 主场球队上半场落后最终获胜 MATCH (t:Team)-[:PLAYED_HOME]->(m:Match) WHERE m.season = '2020-21' AND m.hthg < m.htag AND m.ftr = 'H' WITH COLLECT(DISTINCT t.name) as 主场逆转队 // 客场球队上半场落后最终获胜 MATCH (t:Team)-[:PLAYED_AWAY]->(m:Match) WHERE m.season = '2020-21' AND m.htag < m.hthg AND m.ftr = 'A' WITH 主场逆转队 + COLLECT(DISTINCT t.name) as 逆转球队 UNWIND 逆转球队 as 球队 RETURN DISTINCT 球队 as 逆转获胜球队 ORDER BY 球队
注:hthg是主队上半场进球,htag是客队上半场进球
8. 2000年以来单赛季积分最高的球队
MATCH (t:Team)-[:PLAYED_HOME|:PLAYED_AWAY]->(m:Match) WHERE m.season >= '2000-01' WITH t, m.season as 赛季, SUM(CASE WHEN (t-[:PLAYED_HOME]->(m) AND m.ftr = 'H') OR (t-[:PLAYED_AWAY]->(m) AND m.ftr = 'A') THEN 3 WHEN m.ftr = 'D' THEN 1 ELSE 0 END) as 赛季积分 ORDER BY 赛季积分 DESC LIMIT 1 RETURN t.name as 球队名称, 赛季, 赛季积分
9. 2020/21赛季球队最终排名
MATCH (t:Team)-[:PLAYED_HOME|:PLAYED_AWAY]->(m:Match) WHERE m.season = '2020-21' WITH t, SUM(CASE WHEN (t-[:PLAYED_HOME]->(m) AND m.ftr = 'H') OR (t-[:PLAYED_AWAY]->(m) AND m.ftr = 'A') THEN 3 WHEN m.ftr = 'D' THEN 1 ELSE 0 END) as 总积分, SUM(CASE WHEN t-[:PLAYED_HOME]->(m) THEN m.fthg ELSE m.ftag END) as 总进球, SUM(CASE WHEN t-[:PLAYED_HOME]->(m) THEN m.ftag ELSE m.fthg END) as 总失球 WITH t, 总积分, 总进球 - 总失球 as 净胜球 ORDER BY 总积分 DESC, 净胜球 DESC, 总进球 DESC WITH COLLECT({球队: t.name, 积分: 总积分, 净胜球: 净胜球}) as 排名列表 UNWIND range(0, size(排名列表)-1) as idx RETURN idx+1 as 排名, 排名列表[idx].球队, 排名列表[idx].积分, 排名列表[idx].净胜球
10. 不败纪录最长的球队(单赛季连续不败场次)
MATCH (t:Team)-[:PLAYED_HOME|:PLAYED_AWAY]->(m:Match) WITH t, m ORDER BY t.name, m.date WITH t, COLLECT(CASE WHEN (t-[:PLAYED_HOME]->(m) AND m.ftr = 'H') OR (t-[:PLAYED_AWAY]->(m) AND m.ftr = 'A') OR m.ftr = 'D' THEN 1 ELSE 0 END) as 不败标记列表 // 计算连续不败场次 WITH t, REDUCE(s = [], x in 不败标记列表 | CASE WHEN x = 1 THEN CASE WHEN size(s) = 0 THEN [1] ELSE s[0..size(s)-1] + [s[-1]+1] END ELSE s + [0] END) as 连续场次列表 WITH t, MAX([x in 连续场次列表 WHERE x > 0 | x]) as 最长不败场次 ORDER BY 最长不败场次 DESC LIMIT 1 RETURN t.name as 球队名称, 最长不败场次
内容的提问来源于stack exchange,提问作者Ufomba Prince
相关产品推荐
相关产品推荐

