MySQL Left Join帮助

时间:2011-09-01 21:54:22

标签: mysql join left-join

好的,我正在使用PHP和MySQL来创建一个战队名单页面。我有几个不同的表,我需要用于此查询。这是我的表格的布局:

  • 会员 - 普通会员表
  • roster_members - memberID,gameID,rosterXP(该成员为该名册获得的经验值)
  • clan_ranks - title,minimumXP
  • roster_games - 特定游戏的表格,其成员是
  • 的一部分

所以我想要做的是创建一个按队列级别对成员进行分组的查询(minimumXP按降序排列)。他们的氏族等级由clan_rank minimumXP低于roster_member(WHERE minimumXP< rosterXP LIMIT 1)决定。我该如何创造这样的东西?我假设我需要使用左连接或右连接......不确定区别是什么。无论如何,这是我提出的查询,但我很确定它不会起作用。如果有人可以帮我指出我需要添加的任何内容,我将不胜感激。

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 :(得分:0)

我可能会理解你的目标。如果是这样的话,我认为你的意思是你不想按照战队排名进行分组,正如你所说的那样 - 我认为你要求根据战队等级加入。

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就足够了。

LEFTRIGHTINNER联接之间的区别如下:

  • INNER JOIN会将结果限制为完全匹配“双方”的记录(根据{{1},联接语句的“左”和“右”表中的记录存在}子句)
  • A ON表示将包含指定给联接的“左”的表的所有记录,即使这些表的记录不存在。对'。如果记录不存在,则LEFT JOIN值将替换为该表指定的每个字段。
  • NULL恰好与RIGHT JOIN相反。

请注意,我重新安排了字段的位置。这是为了便于阅读,基于LEFT JOIN中不存在记录的可能性。如果它们不存在,您看到的第一个字段将包含数据(来自roster_members),结果集中右侧的字段将为clan_ranks。这绝不是一种要求 - 只是一种惯例。

此外,我删除了数据库前缀并添加了占位符以便于阅读。

答案 1 :(得分:0)

这里棘手的问题是成员与部族之间的关系。假设氏族等级包含

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

有120分的人可能是一个chieftan。但是尝试将此实现为返回chieftan级别的SQL查询有点棘手。实际上,尽管可以编写一个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;