2010-10-02 2 views
0

У меня есть следующие структуры таблицы:MySQL Query Помощь

спички:

+-------------------+---------------------------+------+-----+-------------------+-----------------------------+ 
| Field    | Type      | Null | Key | Default   | Extra      | 
+-------------------+---------------------------+------+-----+-------------------+-----------------------------+ 
| id    | bigint(20)    | NO | PRI | NULL    | auto_increment    | 
| creator_id  | bigint(20)    | NO |  | NULL    |        | 
| mode    | enum('versus','freeplay') | NO |  | NULL    |        | 
| name    | varchar(100)    | NO |  | NULL    |        | 
| team_1_id   | varchar(100)    | NO |  | NULL    |        | 
| team_2_id   | varchar(100)    | NO |  | NULL    |        | 
+-------------------+---------------------------+------+-----+-------------------+-----------------------------+ 

команда:

+--------------+--------------+------+-----+---------+----------------+ 
| Field  | Type   | Null | Key | Default | Extra   | 
+--------------+--------------+------+-----+---------+----------------+ 
| id   | bigint(20) | NO | PRI | NULL | auto_increment | 
| creator_id | bigint(20) | NO | MUL | NULL |    | 
| name   | varchar(100) | NO |  | NULL |    | 
+--------------+--------------+------+-----+---------+----------------+ 

Мне нужна запрос, где мы получаем все матчи из таблицы спичек вместе с имя команды из таблицы команд, учитывая, что, когда режим «против», имя команды берется из таблицы команд, но когда режим «freeplay», имя команды - team_1_id или team_2_id (они могут удерживайте строки, поэтому они являются varchar вместо int), не заходя в таблицу команд.

Любая помощь в этом отношении будет очень заметной.

Спасибо.

+1

Таким образом, вы хотите сказать, что ваши поля означают разные вещи в зависимости от того, что хранится в них? Если это так, возможно, вам не следует запрашивать SQL-запрос, но и советы о том, как вы должны перепроектировать свою базу данных. – Tomalak

+0

Приносим извинения за несвязанный вопрос, но мне было интересно, как можно создать/создать табличную таблицу с обычным текстом, такую ​​как две опубликованные выше? –

+0

FreekOne - 'DESCRIBE TableName' вернет данные. Если вы используете клиент командной строки MySQL, он будет отображаться в том виде, в котором он находится. – Hammerite

ответ

1

Использование:

SELECT m.id, 
     m.creator_id, 
     m.mode, 
     m.name, 
     m.team_1_id, 
     m.team_2_id 
    FROM MATCHES m 
WHERE m.mode = 'freeplay' 
UNION ALL 
    SELECT m.id, 
      m.creator_id, 
      m.mode, 
      m.name, 
      t1.name, 
      t2.name 
    FROM MATCHES m 
LEFT JOIN TEAMS t1 ON t1.id = m.team_1_id 
LEFT JOIN TEAMS t2 ON t2.id = m.team_2_id 
    WHERE m.mode = 'versus' 
+0

Большое спасибо ... Запрос, похоже, работает ... Был ли один вопрос, хотя ... Будет ли это влиять на производительность при разбиении моего запроса на 10 строк за раз? В таблице содержится около 100 тыс. Записей о производстве ... – GeekTantra

+0

GeekTantra: вам нужно обратиться к структуре таблицы, чтобы получить лучшую производительность. Либо сохраните имя команды в таблице «MATCHES», либо создайте соответствующие INT INTs команды team_x_id, потому что INTs быстрее, чем VARCHAR (4+), и это устранит необходимость в UNION. –

0

Во-первых, я бы предложил вам немного изменить структуру вашего стола. Вместо использования team_X_id для имени или идентификатор, используйте его только для идентификатора. Добавьте дополнительный столбец для team_X_name, в который вы можете поместить строку. Таким образом вы можете определить внешние ключи и иметь правильный тип данных. Установите для поля team_X_id значение null и team_X_name для имени команды в режиме freeplay и установите team_X_id в идентификатор команды в режиме против.

Тем не менее, это должно делать то, что вы хотите:

SELECT mode, 
     IF(team_1.id IS NULL, team_1_id, team_1.name), 
     IF(team_2.id IS NULL, team_2_id, team_2.name), 
    FROM matches 
     LEFT JOIN teams AS team_1 ON (matches.team_id_1=team_1.id) 
     LEFT JOIN teams AS team_2 ON (matches.team_id_2=team_2.id); 

редактировать: На самом деле, может быть, я неправильно понял дизайн. Если вы говорите, флаг режима «Freeplay» означает ни team_X_id будет фактическая команда идентификатор, то вам необходимо немного другой запрос:

SELECT mode, 
     IF(mode = 'freeplay' OR team_1.id IS NULL, team_1_id, team_1.name), 
     IF(mode = 'freeplay' OR team_2.id IS NULL, team_2_id, team_2.name), 
    FROM matches 
     LEFT JOIN teams AS team_1 ON (matches.team_id_1=team_1.id) 
     LEFT JOIN teams AS team_2 ON (matches.team_id_2=team_2.id); 

Но я бы сильно предложить улучшение вашего дизайна БД.

+0

Спасибо за помощь, но проблема с вашим запросом заключается в том, что Joins не возможны, когда режим «freeplay», поскольку команда___ид будет содержать строку имени вместо внешнего ключа, указывающего на таблицу команд. – GeekTantra

+0

Именно поэтому используются ЛЕВОЕ СОЕДИНЕНИЕ. Именно поэтому дизайн стола должен быть улучшен. –

0

режим ВЫБРАТЬ случай, когда 'против' THEN t1.name ELSE team_1_id END AS имя из спичек LEFT JOIN команд t1 ON t1.id = team_1_id

Сделайте то же самое для команды 2 и добавить пункт, где в соответствии с ваша потребность

Смежные вопросы