我正在尝试下一场比赛周的比赛。游戏周是指比赛进行时,我们可以具有以下类型的游戏周:20、21、22、23。每个游戏周都播放到特定日期。现在所有的比赛都有特定的状态,如果状态值为5,我可以查看是否在特定游戏周的比赛中进行过比赛,否则,状态为:1、2、3、4。
主要问题和数据结构
主要问题:游戏周。我想返回已经进行的比赛的下一个比赛周,所以假设我有以下比赛:
| id | round.id | status | gameweek | date
1 488 5 1 1/07/2018
2 488 5 1 1/07/2018
3 488 5 1 1/07/2018
4 488 1 2 7/07/2018
5 488 1 2 7/07/2018
6 488 1 2 7/07/2018
7 488 1 3 16/07/2018
8 488 1 3 16/07/2018
9 488 1 3 16/07/2018
结果应为:7、8、9,我的实际查询正确返回了此值,但假设所有matches
的值为status
5(因此所有matches
都已播放),查询将返回空结果。
因此,我尝试处理这种情况以返回最后一个gameweek
(如果matches
的所有round
都已播放),但是我得到了:
SQLSTATE [42000]:语法错误或访问冲突:1140在没有GROUP BY的聚合查询中,SELECT列表的表达式#1包含非聚合列'y.gameweek';这与sql_mode = only_full_group_by
不兼容
这是我的查询
SELECT m.id, m.round_id, m.datetime,
CASE m.status
WHEN 1 THEN 'scheduled'
WHEN 2 THEN 'postponed'
WHEN 3 THEN 'canceled'
WHEN 4 THEN 'playing'
WHEN 5 THEN 'finished'
END AS match_status,
m.gameweek, m.home_team_id, m.home_team_half_time_score, m.home_team_score,
m.home_extra_time, m.home_penalties, m.away_team_id, m.away_team_half_time_score,
m.away_team_score, m.away_extra_time, m.away_penalties, m.venue_id,
m.venue_attendance, m.aggregate_match_id,
t.name AS home_team_name,
t_info.shield_link AS home_team_shield,
t2.name AS away_team_name,
t2_info.shield_link AS away_team_shield,
c.name AS competition_name,
c.id AS competition_id,
r.name AS round_name
FROM `match` m
LEFT JOIN team t ON m.home_team_id = t.id
LEFT JOIN team_info t_info ON t.id = t_info.team_id
LEFT JOIN team t2 ON m.away_team_id = t2.id
LEFT JOIN team_info t2_info ON t2.id = t2_info.team_id
LEFT JOIN competition_rounds r ON m.round_id = r.id
LEFT JOIN competition_seasons s ON r.season_id = s.id
LEFT JOIN competition c ON c.id = s.competition_id
WHERE 1 AND m.status IN (1, 2, 3, 4, 5) AND m.round_id IN (:round_id1) AND m.gameweek = (SELECT COALESCE(y.gameweek, MAX(x.gameweek)) gameweek
FROM `match` x
LEFT JOIN
(SELECT MIN(gameweek) gameweek
FROM `match`
WHERE status < 5
) y ON y.gameweek = x.gameweek ) ORDER BY m.datetime DESC LIMIT 10
我该如何解决?
谢谢。
其他详细信息
在查询的第一部分中,我仅选择要从联接表中返回的字段。使用存储所有匹配项的主表匹配项进行选择。我在表team和team_info上加入了join,后者获取了参加比赛的两个团队的信息。
在此之后,我加入了Competition_rounds,获取了该回合的详细信息,该回合仅仅是比赛的组织,与赛季相同,例如:
round.name = Regular Season | season.id = 5 season.name = 2017/2018 | id = 5
这个问题并不是很重要,但是我试图解释所有查询活动。
在where子句中,我获得所有具有所有可用状态作为状态的匹配项:1、2、3、4、5(您可以在查询字段选择器案例中找到状态描述)。后来我还有一个过滤器,返回这些回合中所有的比赛:10、488、392、70。
答案 0 :(得分:1)
这是导致问题的查询部分:
public class Test {
public static final Test TEST_VALUE = new Test(42);
public static final Test OTHER_TEST_VALUE = new Test(1337);
private int val;
private final String oldEnumName;
private Test(int val, String oldEnumName) {
this.val = val;
this.oldEnumName = oldEnumName;
}
public void increment() {
val++;
}
public int getVal() {
return val;
}
public String name() {
return oldEnumName;
}
public static Test valueOf(String name)
...
问题是m.gameweek = (SELECT COALESCE(y.gameweek, MAX(x.gameweek)) gameweek
FROM `match` x LEFT JOIN
(SELECT MIN(gameweek) gameweek
FROM `match`
WHERE status < 5
) y
ON y.gameweek = x.gameweek
)
未聚合。您可以通过添加y.gameweek
来解决此问题:
GROUP BY y.gameweek
但是,更简单的表达式是:
m.gameweek = (SELECT COALESCE(y.gameweek, MAX(x.gameweek)) gameweek
FROM `match` x LEFT JOIN
(SELECT MIN(gameweek) gameweek
FROM `match`
WHERE status < 5
) y
ON y.gameweek = x.gameweek
GROUP BY y.gameweek
)
m.gameweek = (SELECT m2.gameweek
FROM `match` m2
ORDER BY (status < 5) DESC,
(CASE WHEN status < 5 THEN gameweek END) ASC,
gameweek DESC
LIMIT 1
)
的第一个键将带有ORDER BY
的行放在第一位。第二个按status < 5
的顺序升序排列。因此,结果是第一行将是gameweek
,最小值为status < 5
。
这些都不存在,然后第三个键起作用,您将获得最大值。
另一个版本使用条件聚合:
gameweek