how to output a standings table on the fly from a mysql table of football [soccer] results?

后端 未结 3 1825
天命终不由人
天命终不由人 2020-12-13 16:07

I have been trying to find something about this topic and I can\'t seem to find anything, there were a few questions on here but they didn\'t work for my particular project.

相关标签:
3条回答
  • 2020-12-13 16:17
    // connection stuff
    $sql = 'select * from matchesTable';
    $result = mysql_query($sql)
    
    $standings = array ();
    $standingTemplate = array ('matches' => 0, 'wins' => 0, 'draws' => 0, 'losses' => 0, 'goalsfor' => 0, 'goalsagainst' => 0, 'goalsdiff' => 0, 'points' => 0);
    
    while ($row = mysql_fetch_assoc($result)) 
    {
        handleMatch($row['hometeam'], $row['goalsfor'], $row['goalsagainst']);
        handleMatch($row['awayteam'], $row['goalsfor'], $row['goalsagainst']);
    
        print_r( usort(standings, 'comparePoints') );  // up to you to format the output as you like
    }
    
    function handleMatch($team, $goalsfor, $goalsagainst)
    {
        global $standings, $standingTemplate;
        if ($goalsfor > $goalsagainst) 
        {
            $points = 3;
            $win = 1;
            $draw = 0;
            $loss = 0;
        }
        elsif ($goalsfor == $goalsagainst) 
        {
            $points = 1;
            $win = 0;
            $draw = 1;
            $loss = 0;
        }
        else 
        {
            $points = 0
            $win = 0;
            $draw = 0;
            $loss = 1;
        }
    
        if ( empty($standings[$team]) )$standing = $standingTemplate;
        else $standing = $standings[$team];
    
        $standing['matches']++;
        $standing['wins'] += $win;
        $standing['draws'] += $draw;
        $standing['losses'] += $loss;
        $standing['goalsfor'] += $goalsfor;
        $standing['goalsagainst'] += $goalsagainst;
        $standing['goalsdiff'] += $goalsfor - $goalsagainst;
        $standing['points'] += $points;
    
        $standings[$team] = $standing;
    
    }
    
    function comparePoints($a, $b)
    {
        if ($a['points'] == $b['points']) 
        {
            if ($a['goalsdiff'] == $b['goalsdiff']) return 0;
            return ($a['goalsdiff'] < $b['goalsdiff']) ? 1 : -1 ;
        }       
        return ($a['points'] < $b['points']) ? 1 : -1 ;
    }
    

    NOTES: I didn't test it and all, might be little bug (some $ or ; missing).

    0 讨论(0)
  • 2020-12-13 16:31

    Recently I had to make quite more extended version of datatable. Although it is based on my own schema, but it maybe useful for someone (it is based on previous a'r answer):

      SELECT
        team_id                                             team_id,
        t.name                                              team_name,
        t.country                                           country,
        count(*)                                            matches,
        SUM(scored)                                         scored_total,
        SUM(conceided)                                      conceided_total,
        count(CASE WHEN scored > conceided
          THEN 1 END)                                       wins,
        count(CASE WHEN scored = conceided
          THEN 1 END)                                       draws,
        count(CASE WHEN scored < conceided
          THEN 1 END)                                       lost,
        sum(scored) - sum(conceided)                        balance,
        sum(
            CASE WHEN scored > conceided
              THEN 3
            ELSE 0 END
            + CASE WHEN scored = conceided
              THEN 1
              ELSE 0 END)                                   points,
        count(CASE WHEN place = 'home'
          THEN 1 END)                                       home_matches,
        count(CASE WHEN place = 'home' AND scored > conceided
          THEN 1 END)                                       home_wins,
        count(CASE WHEN place = 'home' AND scored = conceided
          THEN 1 END)                                       home_draws,
        count(CASE WHEN place = 'home' AND scored < conceided
          THEN 1 END)                                       home_lost,
        SUM(CASE WHEN place = 'home'
          THEN scored
            ELSE 0 END)                                     home_scored,
        SUM(CASE WHEN place = 'home'
          THEN conceided
            ELSE 0 END)                                     home_conceided,
        count(CASE WHEN place = 'away'
          THEN 1 END)                                       away_matches,
        count(CASE WHEN place = 'away' AND scored > conceided
          THEN 1 END)                                       away_wins,
        count(CASE WHEN place = 'away' AND scored = conceided
          THEN 1 END)                                       away_draws,
        count(CASE WHEN place = 'away' AND scored < conceided
          THEN 1 END)                                       away_lost,
        SUM(CASE WHEN place = 'away'
          THEN scored
            ELSE 0 END)                                     away_scored,
        SUM(CASE WHEN place = 'away'
          THEN conceided
            ELSE 0 END)                                     away_conceided,
        GROUP_CONCAT((CASE
                      WHEN scored > conceided
                        THEN 'W'
                      WHEN scored = conceided
                        THEN 'D'
                      WHEN scored < conceided
                        THEN 'L'
                      END) ORDER BY date ASC separator '') streak
      FROM
        (
          (SELECT
             hm.date         date,
             hm.home_team_id team_id,
             hm.score_home   scored,
             hm.score_away   conceided,
             'home'          place
           FROM matches hm
           WHERE hm.season_id = :seasonId)
          UNION ALL
          (SELECT
             am.date         date,
             am.away_team_id team_id,
             am.score_away   scored,
             am.score_home   conceided,
             'away'          place
           FROM matches am
           WHERE am.season_id = :seasonId)
        ) m
        JOIN teams t ON t.id = team_id
      GROUP BY team_id
      ORDER BY points DESC, balance DESC;
    
    0 讨论(0)
  • 2020-12-13 16:32

    First union the scores table together swapping the hometeam with the awayteam and swapping the goal counts. This gives you some source data that is easily aggregated and the query to generate the score card is something like this:

    select 
        team, 
        count(*) played, 
        count(case when goalsfor > goalsagainst then 1 end) wins, 
        count(case when goalsagainst> goalsfor then 1 end) lost, 
        count(case when goalsfor = goalsagainst then 1 end) draws, 
        sum(goalsfor) goalsfor, 
        sum(goalsagainst) goalsagainst, 
        sum(goalsfor) - sum(goalsagainst) goal_diff,
        sum(
              case when goalsfor > goalsagainst then 3 else 0 end 
            + case when goalsfor = goalsagainst then 1 else 0 end
        ) score 
    from (
        select hometeam team, goalsfor, goalsagainst from scores 
      union all
        select awayteam, goalsagainst, goalsfor from scores
    ) a 
    group by team
    order by score desc, goal_diff desc;
    
    0 讨论(0)
提交回复
热议问题