2017-01-22 16 views
2

まず、あいまいなタイトルをお詫びしたいと思います(私が解決しようとしている問題を実際に認識したら、それを改めてお約束します)。PostgreSQL - 1列と2列のユニークな値の個数の選択

プレーヤー:

id name 
-- ---- 
1 John 
2 James 
3 April 
4 Jane 
5 Katherine 

は、私は2つのテーブルには、次のようになりプレーヤー試合を、持っていますマッチ:

id winner loser 
-- ------ ----- 
1 1  2 
2 3  4 

勝者敗者二つIDカラムは、データベースによって生成されたプレーヤー、および値の間の一致を表す一致テーブルのレコードプレーヤーテーブルを参照してください。

は、私は次のように吐き出し、クエリを実行したい:

player.id player.name total_wins total_matches 
--------- ----------- ---------- ------------- 
1   John  1   1 
2   James  0   1 
3   April  1   1 
4   Jane  0   1 
5   Katherine 0   0 

私は現在total_winsを取得するクエリを持っていますが、私はtotal_matchesは、その上にカウントを取得するかどうかはわかりません。

select p.id, p.name, count(m.winner) 
from player p left join match m on p.id = m.winner 
group by p.id, p.name; 

ありがとうございました!

答えて

4

select p.id, p.name, 
     sum(case when m.winner = p.id then 1 end) as total_wins, 
     count(m.id) as total_matches 
from player p 
left join match m on p.id in (m.winner, m.loser) 
group by p.id, p.name; 
+0

ありがとう、これは正しい結果を返すようだ! 'p.id in(m.winner、m.loser)'は 'p.id = m.winner AND p.id = m.loser'と同等ですか? – disposedtrolley

+0

また、ケースステートメントを変更して、m.winner = p.id、次に1 else 0 end'を読み込んで、同じ質問をした他の人のために勝利のないプレーヤーに0を表示するようにしました。 – disposedtrolley

+0

いいえ、 'p.id in(m.winner、m.loser)'は 'p.id = m.winner OR p.id = m.loser'と同じです。つまり、' AND'ではなく 'OR'です。 – krokodilko

1

1つの方法でmatchマッチテーブルが分割されるため、勝敗ごとに1つの行があります。残りはちょうどleft joinと集計です:

select p.id, p.name, coalesce(sum(win), 0) as win, count(m.id) as total_matches 
from player p left join 
    (select match, winner as id, 1 as win, 0 as loss from match 
     union all 
     select match, loser as id, 0 as win, 1 as loss from match 
    ) m 
    on p.id = m.id 
group by p.id, p.name; 
+0

感謝をお試しください!このクエリは機能しますが、0の代わりに5のWINSにnull値が設定されています。 – disposedtrolley

+0

@disposedtrolley。 。 。 'coalesce()'を使うだけです。 –

関連する問題