如何根据返回值执行不同的查询?

时间:2019-03-19 17:48:07

标签: mysql sql

我有一个足球比赛的清单,定义如下:

id |        datetime      | status | gameweek | round_id | home_team_id
 1   2019-03-31 00:00:00      1          29     12696          1243
 2   2019-03-31 00:00:00      1          29     12696          1248
 3   2019-03-31 00:00:00      1          29     12696          1242
 4   2019-03-31 00:00:00      1          29     12696          1246
 5   2019-03-31 00:00:00      1          29     12696          1244
 6   2019-03-31 00:00:00      1          29     12696          1247
 7   2019-03-31 20:30:00      1          29     12696          1241
 8   2019-03-31 00:00:00      1          29     12696          1249
 9   2019-03-31 00:00:00      1          29     12696          2981
 10  2019-03-31 00:00:00      1          29     12696          1259

我需要将所有具有下一个matches的{​​{1}}返回到完成的gameweek的所有gameweek

有些matches没有任何rounds,因此,在这种情况下,应返回在完成的{{1}旁边有gameweek的所有matches }。

我写的查询是这样的:

datetime

这只返回9条记录,我不明白为什么,唯一的原因是一条记录也有时间。

完成match是什么意思?

对于Select m.* from `match` m where round_id = 12696 and m.datetime = (SELECT COALESCE(MIN(CASE WHEN m2.status < 5 THEN m2.datetime END), MAX(m2.datetime)) FROM `match` m2 WHERE m2.round_id = m.round_id) 结束或结束,我的意思是每个matches的状态为matchesmatch。状态5表示3已安排,但尚未播放; 1表示match5已取消。

例如:

finished

如您所见,前三个记录已经播放。在那种情况下,查询需要返回所有3(已播放和已调度),因为id | datetime | status | gameweek | round_id | home_team_id 1 2019-03-20 00:00:00 5 29 12696 1243 2 2019-03-20 00:00:00 5 29 12696 1248 3 2019-03-20 00:00:00 5 29 12696 1242 4 2019-03-31 00:00:00 1 29 12696 1246 5 2019-03-31 00:00:00 1 29 12696 1244 6 2019-03-31 00:00:00 1 29 12696 1247 7 2019-03-31 20:30:00 1 29 12696 1241 8 2019-03-31 00:00:00 1 29 12696 1249 9 2019-03-31 00:00:00 1 29 12696 2981 10 2019-03-31 00:00:00 1 29 12696 1259 29还包含其他尚未播放的matches,因此预期结果都是10条记录。

预期结果:1、2、3、4、5、6、7、8、9、10

另一个重要的事情是某些gameweek没有任何matches,因此,假设这个,我们需要返回即将到来的round,例如:

gameweek

预期结果:4、5、6、7、8、9、10

(在小提琴中,记录7丢失了。)

如果没有matches,但所有id | datetime | status | gameweek | round_id | home_team_id 1 2019-03-20 00:00:00 5 NULL 12696 1243 2 2019-03-20 00:00:00 5 NULL 12696 1248 3 2019-03-20 00:00:00 5 NULL 12696 1242 4 2019-03-31 00:00:00 1 NULL 12696 1246 5 2019-03-31 00:00:00 1 NULL 12696 1244 6 2019-03-31 00:00:00 1 NULL 12696 1247 7 2019-03-31 20:30:00 1 NULL 12696 1241 8 2019-03-31 00:00:00 1 NULL 12696 1249 9 2019-03-31 00:00:00 1 NULL 12696 2981 10 2019-03-31 00:00:00 1 NULL 12696 1259 已完成(状态5),则我们需要返回最新gameweeks的所有matches,例如:

matches

预期结果:9、10

datetime

预期结果:1,2,3,4,

我在这里创建了一个fiddle,涵盖了所有情况。

5 个答案:

答案 0 :(得分:2)

这看起来像是不必要的复杂查询,但确实与上述输出匹配。可能是一个很好的起点。

with current_round as (
    select * 
    from match_case_1
    where round_id = 12696
)
select *
from current_round cr
where
    (
        not exists(select * from current_round where gameweek is null)
    )
    or 
    (
        exists(select * from current_round where status = 1) 
        and not exists(select * from current_round where gameweek is not null)
        and cr.status = 1    
    )
    or 
    (
        not exists(select * from current_round where status = 1)
        and not exists(select * from current_round where gameweek is not null)
        and cast(cr.`datetime` as date) = (
            select max(cast(`datetime` as date)) as `date`
            from current_round
            where status = 5 or status = 3
        )
    );

编辑

DB Fiddle查询发布的场景

  1. https://www.db-fiddle.com/f/2f7NEPo72tUM7zLHBX2GXQ/0
  2. https://www.db-fiddle.com/f/3ghG6zf7hv2SbACL9vtnJa/1
  3. https://www.db-fiddle.com/f/q7DgtJRfDxyPA8bQheRncA/1
  4. https://www.db-fiddle.com/f/tV7VhZg1Ywfx1YmnFMtZdh/1

答案 1 :(得分:1)

鉴于您的比赛看起来并不会经常改变,我的建议是避免让您头疼,并在应用程序层中拆分这些查询(如果存在)

从示例中,您可以向数据库询问一系列问题以获得所需的结果

是否有最低的比赛周未完成第12696轮比赛?

SELECT MIN(gameweek) min_gameweek 
  FROM `match` 
 WHERE round_id = 12696
   AND gameweek IS NOT NULL
   AND status = 1

如果是。.该比赛周的比赛是什么?

SELECT *
  FROM `match` 
 WHERE round_id = 12696
   AND gameweek = :min_gameweek

如果没有。(您不妨尝试在此处找到第12696轮中已完成比赛的最长比赛周,并列出其中的所有比赛)

如果仍然没有。在12696回合没有比赛周的情况下未完成的比赛是什么?

SELECT *
  FROM `match`
 WHERE round_id = 12696
   AND gameweek IS NULL
   AND status = 1

如果没有,.. 他们是在12696回合没有比赛周的情况下完成比赛的最新日期吗?

SELECT MAX(`datetime`) latest_datetime
  FROM `match`
 WHERE round_id = 12696
   AND gameweek IS NULL
   AND status != 1

如果是,那么。.在最近的日期时间中,没有第12696轮比赛周的比赛有哪些?

SELECT *
  FROM `match` 
 WHERE round_id = 12696
   AND `datetime` = :latest_datetime

N.B。这种方法涉及更多查询,但可读性,调试性和灵活性更高,甚至比尝试进行一次怪兽查询还要好

您可能可以将上面的一些查询与增加太多的不透明性结合起来,但是我仍将首先写出每个步骤并对其进行测试

我也将认真建议简化以下整个过程

  • 将每个回合的当前游戏周和最大游戏周存储在圆桌会议中(如果该回合没有游戏周,则为NULL)
  • 仅显示当前一轮比赛中该回合的所有比赛
  • 比赛结束时(或一天/一周结束时),如果所有比赛都结束并且尚未达到最高赔率,则增加当前游戏周数

答案 2 :(得分:0)

只需使用未来1周的过滤器

 select m.* from `match` m 
 WHERE DATE(datetime)>=date(now())
 and DATE(datetime) <= date_add(current_date, INTERVAL 1 week)       
 and m.status =1

答案 3 :(得分:0)

这是您想要的吗?:

SELECT m.*
FROM `match` m 
WHERE m.round_id = 48 AND 
      m.gameweek = (SELECT MAX(m1.gameweek) 
                    FROM `match` m1 
                    WHERE m1.round_id = m.round_id AND m1.status = 1
                   );

通过这种方式,您将获得每场比赛的最后一场比赛gameweek

答案 4 :(得分:0)

如果您要在上个游戏周使用,可以使用子查询。最后一个游戏周将是其他所有周中的最大值。

尝试跟随希望有帮助

select * from `match` m where m.gameweek = (select max(gameweek) from `match`)