1

我正在尝试为我正在制作的游戏设置一个高分板。在棋盘上,我对另外两个棋盘、玩家和武器使用外键。每个分数都存储了玩家在那次跑步中使用的四种武器。表是这样设置的:

Scores
id|playerid|score|weapon0id|weapon1id|weapon2id|weapon3id

Players
id|name

Weapons
id|name

我想从分数表中选择多行,并将 ID 替换为适当的名称。我可以使用以下语句获得正确的玩家名称和一种武器:

SELECT scoreID, Players.playerName, scoreVal,
    Weapons.weaponLabel, scoreW1, scoreW2, scoreW3
FROM Scores, Players, Weapons
WHERE Players.playerID = scorePlayer AND Weapons.weaponID = scoreW0

我看过的所有地方都表明,这是从外键引用的行中获取值的最佳方法。它适用于玩家名称,但似乎无法扩展它以一次填写多个武器名称。对剩余的武器使用 OR 或使用武器 ID IN (w0,w1,w2,w3) 似乎每个武器都有一行,而不是每个武器在适当位置的一行。

有没有办法只使用 select 语句来获得正确的武器名称?或者我是否需要额外的代码循环并用正确的名称替换每个武器 ID?

4

2 回答 2

2

这种设计是有问题的:weapon0..n可能只会导致像这样的困难查询。查询也必须去规范化——例如每个 weapon0..n.

无论如何,查询是错误的,并且将返回比预期更多的行,因为它使用FROM a,b暗示 a 和 b 之间的交叉连接的形式,并且在 WHERE 中没有适当的选择器使其成为等连接。尝试使用普通(INNER)JOIN并使ON每个连接更加明显:

SELECT s.scoreID, p.playerName, s.scoreVal,
    w0.weaponLabel as w0Label,
    w1.weaponLabel as w1Label
    -- etc
FROM Scores s
JOIN Players p ON p.id = s.playerID
JOIN Weapons w0 ON w0.weaponID = s.scoreW0
JOIN Weapons w1 ON w1.weaponID = s.scoreW1
-- etc, ick!!!

到现在为止,为什么去规范化的数据很糟糕应该很明显了! 每列必须与不同的关系(w0、w1 等)连接。

于 2013-05-22T22:12:09.063 回答
0

我通常必须创建一个循环过程,以在每个唯一集的一行中获取所有非规范化列,在您的情况下,播放器是武器标签。

于 2013-05-22T22:11:47.597 回答