简单的Mysql表连接问题
问题描述:
我正在设计一个网站来教我自己如何在mysql中使用表连接,并在早期卡住了。 (这些数字是Wii的朋友代码,如果这能帮助你理解这一点!)简单的Mysql表连接问题
我有3个表:
用户:
id, firstname, surname
游戏:
id, title
号:
number, users_id, game_id
T他的号码是属于用户且与游戏关联的唯一代码。
我想弄出一个特定游戏的数字列表以及它们所属的用户的名字。
我运行查询:
SELECT firstname, surname, number FROM games, users, numbers WHERE numbers.game_id = games.id AND games.title = 'foogame'
例如,获得了所有属于foogame的数字。但是,这会返回没有此游戏代码的任何用户使用来自其他用户的随机代码。我如何使这个查询只返回实际上有该游戏代码的用户?
答
我觉得它更容易,如果你实际使用联接,因为你不会错过像你第一次做的一样加入条件。
SELECT firstname, surname, number FROM users u INNER JOIN numbers n on n.users_id = u.id INNER JOIN games g on n.game_id = g.id WHERE g.title = 'foogame'
INNER JOIN是你做了什么,相当于 - 它明确限制。
答
啊 - 只是写这个问题帮助了我!
SELECT firstname, surname, number
FROM games, users, numbers
WHERE numbers.game_id = games.id AND
games.title = 'foogame' AND
games.user_id = users.id
简单!
优化此任何想法?
答
SELECT firstname, surname, number
FROM games g, numbers n, users u
WHERE g.title = 'foogame'
AND n.game_id = g.id
AND u.id = n.users_id
要进行优化,创建索引:
CREATE INDEX ix_game_title ON games (title)
CREATE INDEX ix_numbers_game ON numbers (game_id, users_id)
,当然,让你games.id
和users.id
主键。
如果你曾经想在给予一定user
所有games
搜索numbers
,您还需要:
CREATE INDEX ix_numbers_users ON numbers (users_id)
答
您需要将numbers
表的users_id
和game_id
列链接到用户和游戏ID栏。 只需添加:
AND users_id = users.id
AND game_id = games.id
你也可以使用一个JOIN
来代替。
答
要跟进Tom的回答......如果你是MySQL的新手,我建议你逐步分解它,并且非常清楚从哪里抓取什么东西。您可以将它视为两个表格的连接,其中第三个点在其中跳跃。您还可以使用括号,在几个月后回到它时允许分离。
SELECT firstname, surname, number
FROM
(
(users u INNER JOIN numbers n ON(n.user_id = u.id))
INNER JOIN games g ON(n.game_id = g.id)
)
WHERE g.title = 'foogame'
答
我建议先从一个变化开始。
甚至不要调用任何对象或属性的“数字”。
在这种情况下,可能分别调用表格和列'game_code'和games_codes'。
那么接下来:
SELECT firstname, surname, number
FROM games, users, numbers
WHERE numbers.game_id = games.id AND games.title = 'foogame'
成为
SELECT firstname, surname, game_code
FROM games g, users u, game_codes gc
WHERE gc.game_id = g.id AND g.title = 'foogame'
,当然还有其他的联接
AND gc.users_id = u.id
你在做什么在你的例子是笛卡尔乘积(所有行交叉针对来自其他表的行的所有其他组合)。您希望在id列上使用连接来减少数据集,然后再击中“where”子句。 – 2009-02-18 21:35:13
@Andrew:大多数RDBMS品牌知道如何相同地优化这两种情况。如果你不*在where子句中添加条件,它只是一个笛卡尔积。 – 2009-02-18 21:40:34