MySQL Left Join Help - PullRequest
       1

MySQL Left Join Help

0 голосов
/ 02 сентября 2011

Хорошо, поэтому я использую PHP и MySQL для создания страницы клана. У меня есть несколько разных таблиц, которые мне нужно использовать для этого запроса. Вот как устроены мои столы:

  • Члены - таблица постоянных членов
  • roster_members - memberID, gameID, rosterXP (очки опыта, заработанные участником за этот список)
  • clan_ranks - заголовок, минимумXP
  • roster_games - таблица для определенных игр, членами которых являются

Итак, я хочу создать запрос, который группирует членов по рангу клана (минимум XP в порядке убывания). Их ранг клана определяется тем, что clan_rank минимумXP ниже, чем roster_member (ГДЕ минимальныйXP SELECT cr.id AS crid, cr.title AS rank_title, cr.minimumxp AS rank_min, cr.abbreviation AS rank_abbr, cr.image AS rank_image, rm.memberid AS member_id, rm.rosterxp AS roster_xp, rm.gameid AS game_id FROM ".DB_PREFIX."roster_members AS rm LEFT JOIN ".DB_PREFIX."clan_ranks AS cr ON (cr.minimumXP < rm.rosterXP) WHERE rm.gameID = ".$gameID." GROUP BY cr.id ORDER BY rm.rosterXP DESC

Ответы [ 2 ]

0 голосов
/ 02 сентября 2011

Сложная вещь - это отношения между членами и рядами кланов.Предположим, что в ранге клана содержится

title       minxp
------      ------
chieftan    100
warrior     50
serf        5

Кто-то с 120 очками, вероятно, будет шифтаном.Но попытка реализовать это как запрос SQL, который only возвращает ранг chieftan, немного сложна.Действительно, хотя можно написать SQL-запрос, чтобы вернуть это, жизнь слишком коротка.

Проблема значительно упрощается, если изменить структуру таблицы рангов клана на title, minxp, maxxp.Поддерживать данные немного сложно, но значительно упрощает запросы:

title       minxp    maxxp
------      ------   -----
chieftan    100      999999999
warrior     50       100
serf        5        50

 SELECT ....
 FROM ".DB_PREFIX."roster_members AS rm
 LEFT JOIN ".DB_PREFIX."clan_ranks AS cr 
   ON (rm.rosterXP >= cr.minimumXP AND rm.rosterXP < cr.maximumXP)
 WHERE rm.gameID = ".$gameID."
 GROUP BY cr.id
 ORDER BY rm.rosterXP DESC 

В качестве альтернативы вы можете использовать функцию поиска ....

 CREATE FUNCTION getrank(p_xp INTEGER) 
     RETURNS varchar(50) CHARSET ascii
 READS SQL DATA
 BEGIN
   DECLARE l_rank VARCHAR(50);

   SELECT title
   INTO l_rank
   FROM clan_ranks
   WHERE minxp<p_xp
   ORDER BY minxp DESC
   LIMIT 0,1;

   RETURN l_rank;
 END;
0 голосов
/ 02 сентября 2011

Я думаю Я мог бы понять, какова ваша цель.Если это так, я не думаю, что вы хотите группировать по рангу клана, как вы заявляете - я думаю, что вы просите присоединиться на основе ранга клана.

SELECT rm.memberid     AS member_id, 
       rm.rosterxp     AS roster_xp, 
       rm.gameid       AS game_id,
       cr.id           AS crid, 
       cr.title        AS rank_title, 
       cr.minimumxp    AS rank_min, 
       cr.abbreviation AS rank_abbr, 
       cr.image        AS rank_image
FROM roster_members AS rm
LEFT JOIN clan_ranks AS cr ON cr.minimumXP = 
    (SELECT crm.minimumXP
        FROM clan_ranks crm
        WHERE crm.minimumXP < rm.rosterXP
        ORDER BY minimumXP DESC limit 1)
WHERE rm.gameID = :game_id
ORDER BY rm.rosterXP DESC 

* LEFT JOIN тольконеобходимо, если у вас есть значения в roster_members.rosterXP, которые ниже, чем ваши самые низкие clan_ranks.minimumXP.Если это не случай, то будет достаточно INNER JOIN.

Разница между объединениями LEFT, RIGHT и INNER заключается в следующем:

  • INNER JOIN ограничит результаты записями, которые полностью соответствуют «обеим сторонам» (записи в таблице «слева» и «справа» оператора соединения существуют на основе предложения ON)
  • A LEFT JOIN заявляет, что все записи для таблиц, указанных слева от объединения, будут включены, даже если записи для таблиц направо'.Если записи не существуют, NULL значения будут заменены для каждого из полей, указанных для этой таблицы.
  • A RIGHT JOIN является обратной стороной LEFT JOIN.

Обратите внимание, что я переставил расположение полей.Это для удобочитаемости, исходя из возможности того, что записи в clan_ranks не существуют.Если они не существуют, первые поля, которые вы увидите, будут содержать данные (из roster_members), а поля, расположенные справа налево в наборе результатов, будут NULL.Это никоим образом не является обязательным требованием - это просто соглашение.

Кроме того, я удалил префиксы базы данных и добавил заполнитель для удобства чтения.

...