2016-06-11 4 views
0

У меня есть два стола «спички» и «противники».Вычислить выигранные, завязанные и утерянные игры в postgresql

Матчи

id | date 
---+------------ 
1 | 2016-03-21 21:00:00 
2 | 2016-03-22 09:00:00 
... 

Противники (оценка является нулевым, если не играл)

id | match_id | team_id | score 
---+----------+---------+------------ 
1 | 1  | 1  | 0 
2 | 1  | 2  | 1 
3 | 2  | 3  | 1 
4 | 2  | 4  | 1 
4 | 3  | 1  | 
4 | 3  | 2  | 
.... 

Цель состоит в том, чтобы создать следующую таблицу

Team | won | tie | lost | total 
-----+-----+-----+------+---------- 
2 | 1 | 0 | 0 | 1 
3 | 0 | 1 | 0 | 1 
4 | 0 | 1 | 0 | 1 
1 | 0 | 0 | 1 | 1 

Postgres v9.5

Как это сделать? (. Im открыты возможно перемещение «забить», чтобы где-то в моей модели, если это имеет смысл)

ответ

0

разделяй и властвуй мой сын

with teams as (
    select distinct team_id from opponents 
), 
teamgames as (
    select t.team_id, o.match_id, o.score as team_score, oo.score as opponent_score 
    from teams t 
    join opponents o on t.team_id = o.team_id 
    join opponents oo on (oo.match_id = o.match_id and oo.id != o.id) 
), 
rankgames as (
    select 
     team_id, 
     case 
      when team_score > opponent_score then 1 
      else 0 
     end as win, 
     case 
      when team_score = opponent_score then 1 
      else 0 
     end as tie, 
     case 
      when team_score < opponent_score then 1 
      else 0 
     end as loss 
    from teamgames 
), 
rank as (
    select 
     team_id, sum(win) as win, sum(tie) as tie, sum(loss) as loss, 
     sum(win * 3 + tie * 1) as score 
    from rankgames 
    group by team_id 
    order by score desc 
) 
select * from rank; 

Note1: Вы, наверное, не нужен первый «с», как вы, вероятно, уже таблицу с одной записью в команде

Примечание2: я думаю, что вы можете достичь того же результата с помощью одного запроса, но в этом случае шаги понятнее

+0

Thansk @ Jack, это делает трюк. Я думал в совершенно другом направлении с LATERAL соединениями и т. Д. – Marcus