好的,我正在使用PHP和MySQL来创建一个战队名单页面。我有几个不同的表,我需要用于此查询。这是我的表格的布局:
所以我想要做的是创建一个按队列级别对成员进行分组的查询(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
答案 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
就足够了。
LEFT
,RIGHT
和INNER
联接之间的区别如下:
INNER JOIN
会将结果限制为完全匹配“双方”的记录(根据{{1},联接语句的“左”和“右”表中的记录存在}子句)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;