Есть ли запрос, чтобы получить набор результатов - PullRequest
0 голосов
/ 23 мая 2019

У меня есть таблица «совпадений», содержащая данные примерно такого типа:

team1   team2   result_team_1   result_team_2
TEAM1   TEAM2   2               9
TEAM3   TEAM4   0               0

Есть ли способ (запрос, просмотр и т. Д.) Для получения набора результатов, например

1 team2 9 2 3
2 team1 2 9 0
3 team3 0 0 1
4 team4 0 0 1

Как типичная таблица результатов, известная в каждом виде спорта.

Ответы [ 2 ]

1 голос
/ 23 мая 2019

Этот запрос будет выполняться на MySQL 5.x. Он использует переменные MySQL для эмуляции функции ROW_NUMBER. Если вы используете MySQL 8+, я бы порекомендовал второй запрос, поскольку переменные в MySQL 8 устарели и могут быть удалены в будущих версиях.

SELECT *,
       @rank := @rank + 1 AS position
FROM (
  SELECT team, 
         SUM(points) AS points, 
         SUM(goals_for) AS goals_for, 
         SUM(goals_against) AS goals_against
  FROM (
    SELECT team1 AS team,
           CASE WHEN m.result_team_1 > m.result_team_2 THEN 3
                WHEN m.result_team_1 = m.result_team_2 THEN 1
                ELSE 0 END AS points,
           m.result_team_1 AS goals_for,
           m.result_team_2 AS goals_against
    FROM matches m
    UNION ALL
    SELECT team2 AS team,
           CASE WHEN m.result_team_2 > m.result_team_1 THEN 3
                WHEN m.result_team_2 = m.result_team_1 THEN 1
                ELSE 0 END AS points,
           m.result_team_2 AS goals_for,
           m.result_team_1 AS goals_against
    FROM matches m
  ) r
  GROUP BY team
  ORDER BY points DESC, SUM(r.goals_for) - SUM(r.goals_against) DESC, goals_for DESC
) r
CROSS JOIN (SELECT @rank := 0) v
ORDER BY position

Выход:

team    points  goals_for   goals_against   position
TEAM2   3       9           2               1
TEAM3   1       0           0               2
TEAM4   1       0           0               3
TEAM1   0       2           9               4

Демонстрация на dbfiddle

Этот запрос опирается на MySQL 8+, поскольку он использует CTE и функцию ROW_NUMBER() (для окончательного ранжирования):

WITH teams AS (
  SELECT team1 AS team FROM matches
  UNION
  SELECT team2 FROM matches
),
results AS (
  SELECT t.team,
         SUM(CASE WHEN m.team1 = t.team AND m.result_team_1 > m.result_team_2 THEN 3
                  WHEN m.team2 = t.team AND m.result_team_2 > m.result_team_1 THEN 3
                  WHEN (m.team1 = t.team OR m.team2 = t.team) AND m.result_team_1 = m.result_team_2 THEN 1
                  ELSE 0 END) AS points,
         SUM(CASE WHEN m.team1 = t.team THEN m.result_team_1
                  ELSE m.result_team_2 END) AS goals_for,
         SUM(CASE WHEN m.team1 = t.team THEN m.result_team_2
                  ELSE m.result_team_1 END) AS goals_against
  FROM teams t
  JOIN matches m ON m.team1 = t.team OR m.team2 = t.team
  GROUP BY t.team)
SELECT t.team, r.points, r.goals_for, r.goals_against, 
       ROW_NUMBER() OVER(ORDER BY r.points DESC, r.goals_for - r.goals_against DESC, r.goals_for DESC) AS position
FROM teams t
JOIN results r ON r.team = t.team
ORDER BY position

Выход:

team    points  goals_for   goals_against   position
TEAM2   3       9           2               1
TEAM3   1       0           0               2
TEAM4   1       0           0               3
TEAM1   0       2           9               4

Демонстрация на dbfiddle

0 голосов
/ 23 мая 2019

Вам нужно UNION ALL, чтобы получить результаты для каждой команды. Тогда агрегируй.

select
  team,
  sum(made) as goals_made,
  sum(got) as goals_got,
  sum(case when made > got then 3 when made = got then 1 else 0 end) as points
from
(
  select team1 as team, result_team_1 as made, result_team_2 as got from matches
  union all
  select team2 as team, result_team_2 as made, result_team_1 as got from matches
) team_results
group by team
order by points;

Замените order by points на то, что вы считаете целесообразным. Начиная с MySQL 8, вы можете использовать ROW_NUMBER для нумерации позиций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...