2017-05-23 10 views
1

私はSQLを初めて使い、オンラインチュートリアルから基本を取り上げようとしています。私は質問に固執し、いくつかのアドバイスを感謝します。PostgreSQLのクエリデータ集計デフォルト値

現在のところ、目標は、クエリを使用してトーナメントのための選手立てテーブルを作成することです。私は2つのテーブルを持っています。選手と試合。

私は勝利を集約する必要があり、これを行うに一致する
tournament=> select * from players; 
id |  name  
----+------------------ 
19 | Melpomene Murray 
20 | Randy Schwartz 
46 | Ricardo 
(3 rows) 


tournament=> select * from matches; 
winner_id | loser_id 
-----------+---------- 
     19 |  20 
(1 row) 

id |  name  | wins | p_matches 
----+------------------+------+----------- 
19 | Melpomene Murray | 1 |   1 
20 | Randy Schwartz | 0 |   1 
46 | Ricardo   | 0 |   0 

今、これは私の最高の推測です:

tournament=> select players.id, players.name, subq.wins, subq2.p_matches from players, 
(select players.id,count(players.id) as wins from players,matches 
where matches.winner_id = players.id group by players.id) as subq, 
(select count(*) as p_matches from matches) as subq2; 

id |  name  | wins | p_matches 
----+------------------+------+----------- 
19 | Melpomene Murray | 1 |   1 
20 | Randy Schwartz | 1 |   1 
46 | Ricardo   | 1 |   1 

トラブルの大きな塊が私の由来サブクエリ。私はそれを個別に実行すると、条件付きのために1行が得られます。私はすべてのIDをゼロに保っている行がゼロであるようにリストしたいと思っています。

tournament=> select players.id,count(players.id) as wins from players,matches 
where matches.winner_id = players.id group by players.id; 
id | wins 
----+------ 
19 | 1 

私はこのようなことができると聞いたことがありますが、私はそれを動作させることができませんでした。思考?

答えて

1

これもあり、私はより可能性の高い優れた(より良い実行しているか分からないが複数のサブクエリ)。

select p.id, 
     p.name, 
     count(case when m.winner_id = p.id then 1 end) won, 
     count(m.*) total 
from players p 
left join matches m 
on m.winner_id = p.id 
or p.id = m.loser_id 
group by p.id, p.name; 

一つはカウントのような集計関数を使用することができ、その場合、グループの結果次に、(プレイヤーIDがその中に存在するか否か)これは、すべてのプレイヤーのレコードを選択し、左がマッチテーブルを結合します。

最初のカウント集計関数は、勝者の列(勝者)のプレーヤーIDを持つ行のみをカウントし、2番目のカウント集計関数はいずれかの列にある場合にカウントします。

+0

これはトリックを行うようだ、と私は十分にその要点を取得します。ありがとうございました! –

0

おそらくこれは

t=# with a as (
select p.*, w.w wins, coalesce(w.w, l.l) p_m 
from players p 
left outer join matches w on w.w = p.id 
left outer join matches l on l.l = p.id 
) 
select id,name, count(wins), count(p_m) 
from a 
group by id, name 
order by id; 
id |  name  | count | count 
----+-------------------+-------+------- 
19 | Melpomene Murray |  1 |  1 
20 | Randy Schwartz |  0 |  1 
46 | Ricardo   |  0 |  0 
(3 rows) 
+0

プレイバイプレイの説明に問題がありますか?私はシバン全体にはかなり新しいので、あなたのクエリがどのように働くのかを理解したいと思います。たとえば、 "select"ではなく "with"コマンドで始まるクエリは見たことがありません。 –

0

簡単な方法は、あなたのselect句でサブクエリを使用している?::

select 
    id, 
    name, 
    (select count(*) from matches m where p.id = m.winner_id) as wins, 
    (select count(*) from matches m where p.id in (m.winner_id, m.loser_id)) as p_matches 
from players p 
order by id; 
+0

私はこの1つのロジックに従うことができますが、質問のそのセクションからプレーヤーにアクセスすることはできません。 ポストグルは私ができるとは思わない: エラー:スキーマ "p"が存在しない –

+0

はい、申し訳ありません、私は 'IN'キーワードを見逃していたので、PostgreSQLは' p.id(m.winner_id、m。 loser_id) 'を関数にするため、' p'がスキーマになります。 –