How to execute different query based on returned value?

sfa*_*oso 6 mysql sql

I have a list of football matches defined as follow:

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
Run Code Online (Sandbox Code Playgroud)

I need to return all the matches which have as gameweek the next gameweek to the finished matches not all.

Some rounds doesn't have any gameweek, so in that case should be returned all the matches which have a datetime next to the finished match.

The query I wrote is this:

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)
Run Code Online (Sandbox Code Playgroud)

this return only 9 records, and I don't understand why, the only reason is that one record have the time too.

What does finished matches mean?

For matches ended or finished I mean that the status of each match is 5 or 3. A status of 1 means that the match is scheduled, but hasn't played yet; 5 means finished and 3 canceled.

eg:

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
Run Code Online (Sandbox Code Playgroud)

as you can see the first three records are already played. In that case the query need to return all the matches (played and scheduled) because the gameweek 29 contains also other matches that hasn't played yet, so the expected result are all the 10 records.

expected result: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

Another important thing is that some round doesn't have any gameweek, so supposing this, we need to return the upcoming matches, eg:

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
Run Code Online (Sandbox Code Playgroud)

expected result: 4, 5, 6, 7, 8, 9, 10

(In the fiddle the record 7 is missing).

If there are no gameweeks, but all the matches are finished (status 5), then we need to return all the matches of the latest datetime, eg:

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      5        NULL     12696          1246
 5   2019-03-31 00:00:00      5        NULL     12696          1244
 6   2019-03-31 00:00:00      5        NULL     12696          1247
 7   2019-03-31 20:30:00      5        NULL     12696          1241
 8   2019-03-31 00:00:00      5        NULL     12696          1249
 9   2019-04-05 00:00:00      5        NULL     12696          2981
 10  2019-04-05 00:00:00      5        NULL     12696          1259
Run Code Online (Sandbox Code Playgroud)

expected result: 9, 10

id |        datetime      | status | gameweek | round_id | home_team_id
 1   2019-03-20 00:00:00      5        28     12696          1243
 2   2019-03-20 00:00:00      5        28     12696          1248
 3   2019-03-20 00:00:00      1        28     12696          1242
 4   2019-03-31 00:00:00      1        28     12696          1246
 5   2019-04-05 00:00:00      5        29     12696          1244
 6   2019-04-05 00:00:00      5        29     12696          1247
 7   2019-04-05 20:30:00      5        29     12696          1241
 8   2019-04-05 00:00:00      5        29     12696          1249
Run Code Online (Sandbox Code Playgroud)

Expected result: 1,2,3,4,

I created a fiddle here which covers all the cases.

Rob*_*lor 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
        )
    );
Run Code Online (Sandbox Code Playgroud)

编辑

关于已发布场景的 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