2014-09-01 1 views
0

Два вопроса о SO, похоже, спрашивают о поведении для эквивалентных запросов MySQL. В обоих случаях соединение выполняется в таблицах с одинаковыми именами столбцов. This poster спрашивает, как устранить дублированные столбцы с тем же именем из результата, и this poster спрашивает, как добиться дублирования столбцов с таким же именем в результате.MySQL: повторяющиеся столбцы с одинаковым именем в соединении

Чтобы проверить это, я создал игрушку таблицы:

mysql> describe table_1; 
+----------+--------------+------+-----+---------+-------+ 
| Field | Type   | Null | Key | Default | Extra | 
+----------+--------------+------+-----+---------+-------+ 
| col_name | varchar(255) | YES |  | NULL |  | 
+----------+--------------+------+-----+---------+-------+ 

mysql> describe table_2; 
+----------+--------------+------+-----+---------+-------+ 
| Field | Type   | Null | Key | Default | Extra | 
+----------+--------------+------+-----+---------+-------+ 
| col_name | varchar(255) | YES |  | NULL |  | 
+----------+--------------+------+-----+---------+-------+ 

Я вставил значение «значение» в обеих таблицах и и выполняется их соединений, в которых JOIN_OP либо «присоединиться» или «левое соединение»:

mysql> select * from table_1 as t1 JOIN_OP table_2 as t2 on t1.col_name = t2.col_name; 
+----------+----------+ 
| col_name | col_name | 
+----------+----------+ 
| value | value | 
+----------+----------+ 

Этот результат соответствует результатам в первом сообщении. В чем разница между двумя запросами и двумя результатами? Почему второй плакат не видит дублирования?

+0

Я просто воссозданы обе таблицы включить «уникальный» ограничение для значений имя_столбца и я получаю тот же результат для обоих присоединиться и оставили присоединиться. Не могли бы вы уточнить, пожалуйста? – Schemer

ответ

1

По умолчанию MySQL будет возвращать все столбцы для всех таблиц, если вы используете *. Два столбца возвращаются как один для table_1 и другой для table_2. Вам нужно будет явно ввести имена столбцов в свой запрос, чтобы получить их так, как вы хотите. Используйте запрос следующим образом:

select t1.col_name from table_1 as t1 JOIN_OP table_2 as t2 on t1.col_name = t2.col_name; 
+0

Это также устраняет дублирование. Но это не объясняет, почему второй плакат не получил никакого дублирования. – Schemer

1

SQL: правила 2003 говорят, что если вы используете USING() условия соединения, избыточный столбец удаляются из выпадающего списка, потому что это совершенно ясно, что столбцы имеют такое же имя и такое же значение.

mysql> select * from table_1 as t1 JOIN table_2 as t2 USING (col_name); 
+----------+ 
| col_name | 
+----------+ 
| value | 
+----------+ 

Принимая во внимание, если вы используете более подробный JOIN ON синтаксис, и вы используете select *, то список выборки сохраняет отдельный столбец из каждой из соединяемых таблиц, хотя в этом случае мы можем сказать, что значение границы быть идентичным.

Но, судя по всему, SQL не достаточно умен, чтобы сделать этот вывод, поскольку условие в предложении ON может быть чем-то иным, чем равенством, например. это может быть ON t1.col_name <> t2.col_name, поэтому оба столбца должны быть сохранены в списке выбора, потому что они будут иметь разные значения.

MySQL 5.0.12 и более поздние версии поддерживают это стандартное поведение (было сделано несколько исправлений, чтобы присоединиться к семантике в MySQL 5.0.12, чтобы быть более стандартным).

Вы можете увидеть более подробное обсуждение здесь: http://bugs.mysql.com/bug.php?id=6489

+0

Это, безусловно, устраняет дублирование. Но, поскольку второй плакат не использовал этот синтаксис, почему он/она не видел никакого дублирования? – Schemer

+2

ОП в этом вопросе сказал: «Когда я получаю результат запроса» - я бы предположил, что они извлекают ассоциативный массив в свое приложение и, естественно, заставляют столбцы с тем же именем сливаться в один элемент массива, один переписывает другой. SQL позволяет наборам результатов иметь более одного столбца с тем же именем столбца, но ассоциативные массивы этого не делают. –