在特定条件下无法返回MAX值

时间:2018-07-08 07:47:41

标签: mysql sql

我正在尝试下一场比赛周的比赛。游戏周是指比赛进行时,我们可以具有以下类型的游戏周:20、21、22、23。每个游戏周都播放到特定日期。现在所有的比赛都有特定的状态,如果状态值为5,我可以查看是否在特定游戏周的比赛中进行过比赛,否则,状态为:1、2、3、4。

我的查询具有以下设计:

 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 (10, 488, 392, 70)  
  AND m.gameweek = (SELECT MAX(m2.gameweek)
  FROM `match` m2 WHERE m2.round_id = m.round_id AND m2.status = m.status) 
  ORDER BY m.datetime DESC LIMIT 10 

主要问题和数据结构

主要问题:游戏周。我想返回已经进行的比赛的下一个比赛周,所以假设我有以下比赛:

| 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

我的查询将返回比赛ID:7、8、9,但应返回:4、5、6,因为是下一个需要玩的游戏周,因此游戏周1已经完全玩完了。

注意到,例如,如果在游戏第1周中几乎没有一场比赛,则查询应返回游戏第1周而不是第2周。

我该如何解决?

谢谢。

其他详细信息

在查询的第一部分中,我仅选择要从联接表中返回的字段。使用存储所有匹配项的主表匹配项进行选择。我在表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。

2 个答案:

答案 0 :(得分:1)

请考虑以下内容:

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(id SERIAL PRIMARY KEY
,played TINYINT NOT NULL
,gameweek INT NOT NULL
);

INSERT INTO my_table VALUES
(1,1,1),
(2,1,1),
(3,1,1),
(4,1,2),
(5,1,2),
(6,0,2),
(7,0,3),
(8,0,3),
(9,0,3);     

SELECT MIN(gameweek) gameweek FROM my_table WHERE played = 0;
+----------+
| gameweek |
+----------+
|        2 |
+----------+

对于所有游戏都可以玩的情况,我想您可以做这样的事情-尽管可能有更优雅的解决方案...

UPDATE my_table SET played = 1;

SELECT COALESCE(y.gameweek,MAX(x.gameweek)) gameweek 
  FROM my_table x 
  LEFT 
  JOIN  
     ( SELECT MIN(gameweek) gameweek 
         FROM my_table 
        WHERE played = 0 
     ) y
    ON y.gameweek = x.gameweek;
+----------+
| gameweek |
+----------+
|        3 |
+----------+

答案 1 :(得分:1)

您的情况以WHERE 1 AND m.status IN (1, 2, 3, 4, 5)开头

我认为1 AND的评估结果为TRUE AND,它并不限制您的结果-这是多余的。 如条件所述,条件status in (1,2,3,4,5)同样适用于条件AND m.gameweek = (SELECT MIN(m2.gameweek) FROM `match` m2 WHERE m2.round_id = m.round_id AND m2.status < 5 ) -如果只能在状态中设置值。

您执行的查询:给我条目,其中游戏周与具有相同round_id和状态的条目的最大游戏周相等。 因此,如果存在另一个具有相同状态的游戏周,则结果将过滤到该状态的最后一周。在您的特殊情况下,一周内的所有比赛都具有相同的状态。

您要执行的查询:从所有游戏周列表中给我最少的游戏周,并至少有一个状态条目<5。

因此,您只想过滤下一周的比赛,因此将使用另一个子查询:

function throw_promise_error (error) {
 return new Promise(function (resolve, reject){
  reject(error)
 })
}