2013-09-16 2 views
2

У меня есть таблица MySQL, в которой я поддерживаю отношения друг к другу. Таблица предназначена для хранения списков партнеров для программы статистики форева. У игрока может быть 0, 1 или 2 партнера.От одного к большому поисковому запросу

Например:

___________________________________ 
| Table index | Partners | Players | 
|  1  |  1 | John | - Singles, no partners 
|  2  |  2 | John | - Doubles, John and Bob 
|  3  |  2 | Bob | - Doubles, John and Bob 
|  4  |  3 | Dave | - Roto doubles, Dave, Bob, John 
|  5  |  3 | Bob | - Roto doubles, Dave, Bob, John 
|  6  |  3 | John | - Roto doubles, Dave, Bob, John 
|  7  |  4 | Dave | - Singles, no partners 
____________________________________ 

Я пишу PHP скрипт для добавления и извлечения партнеров из-за стола и у меня возникли проблемы с моими запросами. Я знаю игроков и хочу получить поле партнеров. Мне нужно выполнить три запроса:

  • не проверять партнеров - Одиночные игры;
  • проверить для конкретного партнера - удваивается с «Dave»;
  • проверить наличие двух конкретных партнеров - удваивается с «Боб и Дейв»;

Если запись существует, я хотел бы ее загрузить, если нет, то я добавлю эту запись в таблицу. Одна из проблем, которые у меня есть, например, у игрока «Джон» есть три записи, ни партнеры, ни один партнер и два партнера. Как указать только вытаскивание ввода 1, а не 2 или 6?

Я искал здесь и нашел несколько примеров, которые близки, но не совсем то, что мне нужно. Этот mySQL: Querying one-to-many -table? почти делает то, что мне нужно, но не совсем.

Любая помощь была бы принята с благодарностью.

Chris

+1

Почему последняя строка, четыре партнера, означает «синглы без партнеров»? – Blazemonger

+3

Вы сохраняете только производную информацию - это будет сложно поддерживать. Вам также не нужно вводить информацию, которая сотрудничает с кем? В этом случае просто поддерживайте таблицу партнерских отношений и получайте количество партнеров для каждого игрока с запросом. – reinierpost

+0

Извините, название столбца «партнеры» было бы лучше названо - «partnerID». Это индекс, указывающий партнерские отношения, а не количество партнеров, которых имеет данный человек. Мой оригинальный пост может ввести в заблуждение. – vrstud

ответ

0

Если я понимаю, ваша схему правильно ваше поле Partners фактически является внешним ключом в таблицу неявных группировок (т.е. было бы лучше назвал TeamID и ключ в таблице под названием Team, где каждая строка представляет собой одно партнерства) ,

Давайте определим полную схему, чтобы мы могли нормально работать (это по существу то же самое, что и ваша таблица, но денормализованная, чтобы сделать ее более понятной, также вы можете просто использовать PlayerId, а не имя, которое позволяет различным игрокам с одинаковыми имя). В вашей таблице «много-ко-многим» здесь есть PlayerTeam.

enter image description here

Мы можем получить TeamID-х и размеры команды для данного игрока, запустив этот запрос

SELECT TeamId, count(PlayerId) as TeamSize 
FROM PlayerTeam 
WHERE TeamId IN (SELECT TeamId FROM PlayerTeam WHERE PlayerId = *your-player-id*) 
GROUP BY TeamId 

И вы можете получить конкретную команду размера путем добавления предложения HAVING:

SELECT TeamId, count(PlayerId) as TeamSize 
FROM PlayerTeam 
WHERE TeamId IN (SELECT TeamId FROM PlayerTeam WHERE PlayerId = *your-player-id*) 
GROUP BY TeamId 
HAVING TeamSize = 2 

Вы также можете избежать запроса один раз на игрока по этому запросу:

SELECT p.Name, p.PlayerId, pt.TeamId, sz.TeamSize 
FROM Player p JOIN PlayerTeam pt USING(PlayerId) 
    JOIN (SELECT TeamId, count(PlayerId) as TeamSize 
     FROM PlayerTeam GROUP BY TeamId) AS sz USING(TeamId) 

Но для эффективного использования этого последнего результата вы должны будете получить результат для подготовки удобно проиндексированного ассоциативного массива (например, $team[UserId][TeamSize] => TeamId) для принятия решений.

+0

Ваша схема почти правильная, у меня есть отдельные таблицы для имен игроков и используйте их индекс в таблице PlayerTeam. Я не думаю, что таблица TEAM имеет отношение к этим запросам. Запросы - это то, что я ищу. Еще один был бы, если бы я знал информацию обо всех трех игроков. Я бы предположил, что мне придется расширить опцию WHERE для первого и второго запросов? – vrstud

+0

Вы правы, таблица Team не используется, я помещаю ее туда, потому что она помогает с интуицией «многие-ко-многим». Да, с другим предложением IN с подзапросом вы можете указать более одного члена команды: '... WHERE TeamId IN (SELECT TeamId FROM PlayerTeam WHERE PlayerId = id1) И TeamId IN (SELECT TeamId FROM PlayerTeam WHERE PlayerId = id2) ... '. Не уверен, насколько это было бы эффективным, но вы можете решить это, если это станет проблемой позже. –

+0

Спасибо, кучка. Я смог заставить запросы работать отлично. Добавление дополнительной проверки идентификатора игрока отлично поработало. – vrstud

Смежные вопросы