This problem was bugging me for the last couple of weeks, but the solution I've reached so far doesn't seem good enough to aleviate the doubts I have.
Problem Statement: Build a table (query) that shows the followings columns (team name, number of matches, victories, defeats, draws, and score) the score of each team is calculated knowing that each victory gives 3 points and a draw gives one point, while defeats don't afect at all.
Table Schemas:
Table "teams":
| Column name | Type |
|---|---|
| id | int |
| name | varchar(50) |
Table "matches":
| Column name | Type |
|---|---|
| id | int |
| team_1 | int |
| team_2 | int |
| team_1_goals | int |
| team_2_goals | int |
Sample Data:
Table "teams":
| id | name |
|---|---|
| 1 | CEARA |
| 2 | FORTALEZA |
| 3 | GUARANY DE SOBRAL |
| 4 | FLORESTA |
Table "matches":
| id | team_1 | team_2 | team_1_goals | team_2_goals |
|---|---|---|---|---|
| 1 | 4 | 1 | 0 | 4 |
| 2 | 3 | 2 | 0 | 1 |
| 3 | 1 | 3 | 3 | 0 |
| 4 | 3 | 4 | 0 | 1 |
| 5 | 1 | 2 | 0 | 0 |
| 6 | 2 | 4 | 2 | 1 |
Expected Output:
| name | matches | victories | defeats | draws | score |
|---|---|---|---|---|---|
| CEARA | 3 | 2 | 0 | 1 | 7 |
| FORTALEZA | 3 | 2 | 0 | 1 | 7 |
| FLORESTA | 3 | 1 | 2 | 0 | 3 |
| GUARANY DE SOBRAL | 3 | 0 | 3 | 0 | 0 |
What I've managed to do so far:
SELECT
t.name,
count(m.team_1) filter(WHERE t.id = m.team_1)
+ count(m.team_2) filter(WHERE t.id = m.team_2) "matches",
count(m.team_1) filter(WHERE t.id = m.team_1 AND m.team_1_goals > m.team_2_goals)
+ count(m.team_2) filter(WHERE t.id = m.team_2 AND m.team_1_goals < m.team_2_goals) "victories",
count(m.team_1) filter(WHERE t.id = m.team_1 AND m.team_1_goals < m.team_2_goals)
+ count(m.team_2) filter(WHERE t.id = m.team_2 AND m.team_1_goals > m.team_2_goals) "defeats",
count(m.team_1) filter(WHERE t.id = m.team_1 AND m.team_1_goals = m.team_2_goals)
+ count(m.team_2) filter(WHERE t.id = m.team_2 AND m.team_1_goals = m.team_2_goals) "draws",
((count(m.team_1) filter(WHERE t.id = m.team_1 AND m.team_1_goals > m.team_2_goals)
+ count(m.team_2) filter(WHERE t.id = m.team_2 AND m.team_1_goals < m.team_2_goals))* 3) +
count(m.team_1) filter(WHERE t.id = m.team_1 AND m.team_1_goals = m.team_2_goals)
+ count(m.team_2) filter(WHERE t.id = m.team_2 AND m.team_1_goals = m.team_2_goals) "score"
FROM
teams t
JOIN matches m ON t.id IN (m.team_1, m.team_2)
GROUP BY t.name
ORDER BY "victories" DESC
which theoretically outputs the correct answer.
I've tried to make it by using fancy things like CASE WHEN or a bigger JOIN but with no good results. What I want to know is if there is a better way to do this query in terms of writing and performance in the server.
Appreciate any help!