MYSQL объединить один столбец из одной таблицы в две count () в другой - PullRequest
2 голосов
/ 11 марта 2020

У меня есть таблица, в которой хранится рейтинг онлайн-игры. Эта таблица (Игроки) имеет 4 столбца (Player_ID, Player_Name, Current_ELO и Player_Status). Я также хочу показать выигранные / проигранные игры, но эта информация находится в таблице повторов, в которой по одной строке на каждую игру. Я могу легко подсчитать количество выигранных или проигранных игр с помощью функции count (*):

select Winner, count(*) from Replays group by Winner;
select Loser, count(*) from Replays group by Loser;

Однако я не могу найти способ объединить обе таблицы, поэтому мой конечный результат выглядит примерно так:

+-------------+-------------+-----------+------------+
| Player_Name | Current_ELO | Won games | Lost games |
+-------------+-------------+-----------+------------+
| John        | 1035        | 5         | 3          |
+-------------+-------------+-----------+------------+

Мое лучшее предположение - это, однако, возвращает слишком много результатов, потому что я не могу сгруппировать "count ()" по Победителю / Проигравшему индивидуально для каждого счета:

select Player_Name,  Current_ELO, Player_Status, count(Winner_Replays.Winner), count(Loser_Replays.Loser) from Players
inner join Replays as Winner_Replays on Winner_Replays.Winner = Players.Player_Name
inner join Replays as Loser_Replays on Loser_Replays.Loser = Players.Player_Name
group by Winner_Replays.Winner order by Current_ELO desc;

В идеале, так как некоторые у игроков может быть 0 побед или 0 поражений, я хотел бы, чтобы это возвращало 0 для тех пользователей, если это вообще возможно. Спасибо!

1 Ответ

3 голосов
/ 11 марта 2020

Вы можете использовать следующее, используя INNER JOIN в списке игроков с их результатами воспроизведения. Вы можете использовать SUM с CASE, чтобы получить количество побед / поражений каждого игрока.

SELECT Players.Player_Name, ANY_VALUE(Current_ELO), ANY_VALUE(Player_Status),
  SUM(CASE WHEN result = 'L' THEN 1 ELSE 0 END) AS Lost_Games, 
  SUM(CASE WHEN result = 'W' THEN 1 ELSE 0 END) AS Won_Games
FROM Players INNER JOIN (
  SELECT 'W' AS result, Winner AS Player_Name FROM Replays
  UNION ALL
  SELECT 'L', Loser FROM Replays
) win_lose ON Players.Player_Name = win_lose.Player_Name
GROUP BY Players.Player_Name
ORDER BY ANY_VALUE(Current_ELO) DESC;

Вы также можете использовать решение LEFT JOIN, например:

SELECT Players.Player_Name, ANY_VALUE(Current_ELO) AS Current_ELO, ANY_VALUE(Player_Status) AS Player_Status,
  COUNT(DISTINCT rLoser.ReplayID) AS Lost_Games, 
  COUNT(DISTINCT rWinner.ReplayID) AS Won_Games
FROM Players
  LEFT JOIN Replays AS rWinner ON rWinner.Winner = Players.Player_Name
  LEFT JOIN Replays AS rLoser ON rLoser.Loser = Players.Player_Name
GROUP BY Players.Player_Name
ORDER BY ANY_VALUE(Current_ELO) DESC;

демо на dbfiddle.uk

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