TL; DR
Вы можете получить желаемые результаты с помощью JOIN
и DISTINCT
SELECT DISTINCT t.team_name, P.player_name
FROM teams AS t
INNER JOIN Players AS p
ON p.team_id = t.team_id;
ПОЛНОЕ ОБЪЯСНЕНИЕ
Следующий запрос не является детерминированным, то есть вы можете запускать один и тот же запрос для одних и тех же данных несколько раз и получать разные результаты:
SELECT team_id
FROM `teams`
WHERE `game_id`= 35
GROUP BY `team_name`;
Многие СУБД даже не позволяютэтот запрос для запуска.Вы заявили, что некоторые команды дублируются, поэтому рассмотрите следующие фиктивные данные:
team_id team_name game_id
------------------------------------
1 The A-Team 35
2 The A-Team 35
3 The A-Team 35
Когда вы группируете по team_name
, вы получаете одну группу, поэтому, если мы начнем с действительного запроса:
SELECT team_name
FROM `teams`
WHERE `game_id`= 35
GROUP BY `team_name`;
Мы ожидаем один результат:
team_name
--------------
The A-Team
Когда вы добавляете team_id
в выборку без агрегатной функции, вам нужно выбрать одно значение для team_id
,но у механизма запросов есть 3 различных значения на выбор, и ни одно из них не является более правильным, чем любое другое.Вот почему что-либо в операторе select должно содержаться внутри группы (или функционально зависеть от чего-либо) или быть частью агрегатной функции.
Состояние MySQL Docs :
В стандартном SQL запрос, включающий предложение GROUP BY, не может ссылаться на неагрегированные столбцы в списке выбора, которые не названы в предложении GROUP BY.Например, этот запрос недопустим в стандартном SQL, поскольку столбец имени в списке выбора не отображается в GROUP BY:
SELECT o.custid, c.name, MAX(o.payment)
FROM orders AS o, customers AS c
WHERE o.custid = c.custid
GROUP BY o.custid;
Чтобы запрос был допустимым, имястолбец должен быть опущен в списке выбора или назван в предложении GROUP BY.
MySQL расширяет использование GROUP BY, так что список выбора может ссылаться на неагрегированные столбцы, не указанные в предложении GROUP BY.Это означает, что предыдущий запрос является допустимым в MySQL.Вы можете использовать эту функцию для повышения производительности, избегая ненужной сортировки и группировки столбцов.Однако это полезно, прежде всего, когда все значения в каждом неагрегированном столбце, не названном в GROUP BY, одинаковы для каждой группы.
Причина, по которой этот пункт существует, является действительной и может сэкономить некоторое время, рассмотрим следующий запрос:
SELECT t.team_id, t.team_name, COUNT(*) AS Players
FROM teams AS t
LEFT JOIN Players AS p
ON p.team_id = t.team_id
GROUP BY t.team_id;
Здесь мы можем включить team_name
в список выбора дажехотя он не входит в группу, но мы можем сделать это безопасно, поскольку team_id
является первичным ключом, поэтому было бы невозможно иметь два разных значения team_name
для одного team_id
.
В любом случае, отвлекаюсь, проблема, с которой вы, скорее всего, столкнулись, заключается в том, что значение, возвращаемое для team_id
в каждом из ваших запросов, вероятно, будет различным в зависимости от контекста запроса и выбранного плана выполнения.
Вы можете получить отдельный список игроков и команд, используя DISTINCT
:
SELECT DISTINCT t.team_name, P.player_name
FROM teams AS t
INNER JOIN Players AS p
ON p.team_id = t.team_id;
Это по сути хак, и хотя он удаляет дублирующиеся записи, он не решает основную проблему, дублирующих записей ипотенциально неоптимальная структура данных.
Если еще не поздно, я пересмотрю ваш дизайн и внесу несколько изменений.Если имена команд должны быть уникальными, то сделайте их уникальными с уникальным ограничением, поэтому вместо того, чтобы работать с дублирующимися записями, вы полностью их предотвращаете.
Возможно, вам следует использовать соединительные таблицы для игроков и игр, т.е.ваши основные столы
Team (team_id, team_name, team_logo etc)
Game (game_id, game_name, etc)
Player (player_id, player_name, player_email, player_mobile etc)
Затем таблицы, чтобы связать их
Team_Game (team_id, game_id)
Team_Player (team_id, player_id)
Это позволяет одному игроку играть за несколько команд или одной команде за участие в нескольких событиях.