Простая проблема Mysql таблицы соединения - PullRequest
1 голос
/ 19 февраля 2009

Я разрабатываю веб-сайт, чтобы научить себя, как использовать соединения таблиц в mysql, и застрял довольно рано. (Цифры - это коды друзей Wii, если это поможет вам разобраться!)

У меня есть 3 таблицы:

Пользователи:

id, firstname, surname

игры:

id, title

номер:

number, users_id, game_id

Число - это уникальный код, который принадлежит пользователю и ассоциируется с игрой.

Я пытаюсь получить список номеров для конкретной игры вместе с именами пользователей, которым они принадлежат.

Я выполняю запрос:

SELECT firstname, surname, number FROM games, users, numbers WHERE numbers.game_id = games.id AND games.title = 'foogame'

например, чтобы получить все числа, принадлежащие foogame. Однако, это возвращает любого пользователя, у которого нет кода для этой игры со случайным кодом другого пользователя. Как сделать так, чтобы этот запрос возвращал только пользователей, у которых есть код для этой игры?

Ответы [ 6 ]

9 голосов
/ 19 февраля 2009

Мне проще, если вы действительно используете соединения, потому что вы не пропустите условие соединения, как в первый раз.

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 является эквивалентом того, что вы сделали - оно ограничивает конкретно.

1 голос
/ 16 октября 2011

Я бы предложил начать с одного изменения изначально.

Даже не называйте объекты или атрибуты «числами».

В этом случае можно вызвать как таблицу, так и столбец '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
1 голос
/ 19 февраля 2009
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 первичные ключи.

Если вы когда-нибудь захотите найти numbers во всех games с учетом определенного user, вам также потребуется:

CREATE INDEX ix_numbers_users ON numbers (users_id)
0 голосов
/ 19 февраля 2009

Чтобы проконтролировать ответ Тома ... Если вы новичок в 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'
0 голосов
/ 19 февраля 2009

Вам необходимо связать столбцы users_id и game_id таблицы numbers с идентификаторами пользователей и игр. Просто добавьте:

AND users_id = users.id
AND game_id = games.id

Вы также можете использовать JOIN вместо.

0 голосов
/ 19 февраля 2009

Ах, мне помог только написание вопроса!

SELECT firstname, surname, number 
FROM   games, users, numbers 
WHERE  numbers.game_id = games.id AND 
       games.title = 'foogame' AND 
       games.user_id = users.id

Simple!

Есть идеи по оптимизации?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...