MySQL 5 оставил неизвестный столбец

У меня был следующий запрос, работающий в mysql 4.1, но не в 5.0:

SELECT * FROM email e, event_email ee 
LEFT JOIN member m on m.email=e.email 
WHERE ee.email_id = e.email_id

Ошибка: 1054 (Неизвестный столбец "e.email" в разделе "on" )

Ответ 1

Вы можете ссылаться только на таблицы, ранее объединенные с предложением JOIN в предложении ON.

SELECT  *
FROM    email e
JOIN    event_email ee 
ON      ee.email_id = e.email_id
LEFT JOIN
        member m
ON      m.email = e.email 

Это можно проиллюстрировать лучше, если я поставлю скобки вокруг ANSI JOINS в исходном запросе:

SELECT  *
FROM    email e,
        (
        event_email ee
        LEFT JOIN
                member m
        ON      m.email = e.email 
        )
WHERE   ee.email_id = e.email_id

Как видите, в круглых скобках нет источника для e.email: вот почему он не может быть решен.

Ответ 2

От страница документации по MySQL

Ранее оператор запятой (,) и JOIN имели одинаковый приоритет, поэтому выражение объединения t1, t2 JOIN t3 интерпретировалось как ((t1, t2) JOIN t3). Теперь JOIN имеет более высокий приоритет, поэтому выражение интерпретируется как (t1, (t2 JOIN t3)). Это изменение влияет на утверждения, которые используют предложение ON, потому что это предложение может ссылаться только на столбцы в операндах соединения, а изменение в приоритете изменяет интерпретацию того, что эти операнды.

Пример:

CREATE TABLE t1 (i1 INT, j1 INT);
CREATE TABLE t2 (i2 INT, j2 INT);
CREATE TABLE t3 (i3 INT, j3 INT);

SELECT * FROM t1, t2 JOIN t3 ON (t1.i1 = t3.i3);

Ранее SELECT был законным из-за неявной группировки t1, t2 as (t1, t2). Теперь JOIN имеет приоритет, поэтому операнды для предложения ON - t2 и t3. Поскольку t1.i1 не является столбцом в любом из операндов, результатом является Неизвестный столбец "t1.i1" в ошибке "on clause". Чтобы разрешить обработку соединения, сгруппируйте первые две таблицы с помощью круглых скобок, чтобы операнды для предложения ON (t1, t2) и t3:

SELECT * FROM (t1, t2) JOIN t3 ON (t1.i1 = t3.i3);

В качестве альтернативы, избегайте использования оператора запятой и вместо этого используйте JOIN:

SELECT * FROM t1 JOIN t2 JOIN t3 ON (t1.i1 = t3.i3);

Это изменение также относится к операторам, которые смешивают оператор запятой с INNER JOIN, CROSS JOIN, LEFT JOIN и RIGHT JOIN, все из которых теперь имеют более высокий приоритет, чем оператор запятой.

Ответ 3

Ответ заключается в том, чтобы поместить инструкцию JOIN непосредственно после таблицы в инструкции FROM, потому что это та таблица, в которую вы соединяетесь:

SELECT * 
FROM email e 
LEFT JOIN member m on m.email=e.email, 
event_email ee 
WHERE ee.email_id = e.email_id