Home > Mobile >  Return teams that have never played each other - SQL
Return teams that have never played each other - SQL

Time:11-16

I have the table matches

id_match id_team1 id_team2
1 USA JPN
2 AUS USA
3 CAN POL
4 POL USA

and the table teams

id_team name
USA United States
JPN Japan
... ...

And i want to return a new table of teams that have never played each other like this

id_team1 id_team2
USA AUS
CAN USA
... ...

I think i have to use cross join and a subtraction but i can't think exactly how to do it. if anyone can think of how to do it, or a simpler way, i'd really appreciate it!

CodePudding user response:

You can cross join the teams table with itself to generate all possible combinations of matches, then exclude those that already happened with not exists:

If you want both team1/team2 and team2/team1 games, then:

select t1.id_team id_team1, t2.id_team id_team2
from teams t1
inner join teams t2 on t1.id_team != t2.id_team
where not exists (
    select 1 from matches m where m.id_team1 = t1.id_team and m.id_team2 = t2.id_team2
)

If you want a single match between each pair of teams, then we need to add some conditional logic:

select t1.id_team id_team1, t2.id_team id_team2
from teams t1
inner join teams t2 on t1.id_team < t2.id_team
where not exists (
    select 1 
    from matches m 
    where t1.id_team = least(m.id_team1, m.id_team2)
      and t2.id_team = greatest(m.id_team1, m.id_team2)
)

CodePudding user response:

SELECT t1.id_team AS team1, t2.id_team AS AS team2
FROM   teams t1
JOIN   teams t2 ON t1.id_team > t2.id_team
LEFT   JOIN matches m ON (m.id_team1, m.id_team2) = (t1.id_team, t2.id_team)
                      OR (m.id_team1, m.id_team2) = (t2.id_team, t1.id_team)
WHERE  m.id_team1 IS NULL
ORDER  BY 1, 2;

The join condition t1.id_team > t2.id_team not only eliminates twice the same team, but also mirrored pairs.

See:

  • Related