Add up conditional counts on multiple columns of the same table

后端 未结 4 1263
清歌不尽
清歌不尽 2021-01-21 01:16

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

4条回答
  •  甜味超标
    2021-01-21 01:52

    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);
    

提交回复
热议问题