I am looking for a \"better\" way to perform a query in which I want to show a single player who he has played previously and the associated win-loss record for each such oppone
For a single 'subject' player, I would simply union the player in both the winning and losing roles, and sum up the wins / losses:
SELECT opponent, SUM(won) as won, SUM(lost) as lost
FROM
(
select w.username AS opponent, 0 AS won, 1 as lost, m.loser_id as me
from "match" m
inner join "player" w on m.winner_id = w.player_id
UNION ALL
select l.username AS opponent, 1 AS won, 0 as lost, m.winner_id as me
from "match" m
inner join "player" l on m.loser_id = l.player_id
) x
WHERE me = 1
GROUP BY opponent;
For a set based operation, we can just left join the players to the same derived union table:
SELECT p.username as player, x.opponent, SUM(x.won) as won, SUM(x.lost) as lost
FROM "player" p
LEFT JOIN
(
select w.username AS opponent, 0 AS won, 1 as lost, m.loser_id as me
from "match" m
inner join "player" w on m.winner_id = w.player_id
UNION ALL
select l.username AS opponent, 1 AS won, 0 as lost, m.winner_id as me
from "match" m
inner join "player" l on m.loser_id = l.player_id
) x
on p.player_id = x.me
GROUP BY player, opponent;
SqlFiddles of both here
One small point - the names of the indices must be unique - presumably you meant:
create index idx_winners on match(winner_id);
create index idx_losers on match(loser_id);