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
Something more readable than my original. Thoughts?
with W as (
select loser_id as opponent_id,
count(*) as n
from match
where winner_id = 1
group by loser_id
),
L as (
select winner_id as opponent_id,
count(*) as n
from match
where loser_id = 1
group by winner_id
)
select player.username, coalesce(W.n, 0) as wins, coalesce(L.n, 0) as losses
from player
left join W on W.opponent_id = player.player_id
left join L on L.opponent_id = player.player_id
where player.player_id != 1;
QUERY PLAN
-----------------------------------------------------------------------------
Hash Left Join (cost=73.78..108.58 rows=1224 width=48)
Hash Cond: (player.player_id = l.opponent_id)
CTE w
-> HashAggregate (cost=36.81..36.83 rows=2 width=4)
Group Key: match.loser_id
-> Seq Scan on match (cost=0.00..36.75 rows=11 width=4)
Filter: (winner_id = 1)
CTE l
-> HashAggregate (cost=36.81..36.83 rows=2 width=4)
Group Key: match_1.winner_id
-> Seq Scan on match match_1 (cost=0.00..36.75 rows=11 width=4)
Filter: (loser_id = 1)
-> Hash Left Join (cost=0.07..30.15 rows=1224 width=44)
Hash Cond: (player.player_id = w.opponent_id)
-> Seq Scan on player (cost=0.00..25.38 rows=1224 width=36)
Filter: (player_id <> 1)
-> Hash (cost=0.04..0.04 rows=2 width=12)
-> CTE Scan on w (cost=0.00..0.04 rows=2 width=12)
-> Hash (cost=0.04..0.04 rows=2 width=12)
-> CTE Scan on l (cost=0.00..0.04 rows=2 width=12)
The above has a performance killer with the player_id != 1. I think I can avoid that by only scanning the results of the joins, no?
explain with W as (
select loser_id as opponent_id,
count(*) as n
from match
where winner_id = 1
group by loser_id
),
L as (
select winner_id as opponent_id,
count(*) as n
from match
where loser_id = 1
group by winner_id
)
select t.* from (
select player.player_id, player.username, coalesce(W.n, 0) as wins, coalesce(L.n, 0) as losses
from player
left join W on W.opponent_id = player.player_id
left join L on L.opponent_id = player.player_id
) t
where t.player_id != 1;
QUERY PLAN
-----------------------------------------------------------------------------
Hash Left Join (cost=73.78..74.89 rows=3 width=52)
Hash Cond: (player.player_id = l.opponent_id)
CTE w
-> HashAggregate (cost=36.81..36.83 rows=2 width=4)
Group Key: match.loser_id
-> Seq Scan on match (cost=0.00..36.75 rows=11 width=4)
Filter: (winner_id = 1)
CTE l
-> HashAggregate (cost=36.81..36.83 rows=2 width=4)
Group Key: match_1.winner_id
-> Seq Scan on match match_1 (cost=0.00..36.75 rows=11 width=4)
Filter: (loser_id = 1)
-> Hash Left Join (cost=0.07..1.15 rows=3 width=44)
Hash Cond: (player.player_id = w.opponent_id)
-> Seq Scan on player (cost=0.00..1.05 rows=3 width=36)
Filter: (player_id <> 1)
-> Hash (cost=0.04..0.04 rows=2 width=12)
-> CTE Scan on w (cost=0.00..0.04 rows=2 width=12)
-> Hash (cost=0.04..0.04 rows=2 width=12)
-> CTE Scan on l (cost=0.00..0.04 rows=2 width=12)