MySQL ПОКИНУЛ JOIN после изменений 5.0.12 - Как переписать запрос
-
22-08-2019 - |
Вопрос
После версии 5.0.12 MySQL изменил синтаксис для левых соединений, чтобы соответствовать стандарту SQL2003.Итак
... FROM t1 , t2 LEFT JOIN t3 ON (expr)
должен быть переписан как
... FROM (t1 , t2) LEFT JOIN t3 ON (expr
или же он будет проанализирован как ... FROM t1 , (t2 LEFT JOIN t3 ON (expr))
Теперь у меня есть древнее приложение, которое я портирую с MySQL 3.23 (eek!) на 5.1, и старый код содержит этот запрос:
select b.*, c.*, g.*, p.perfname, p.persname
from bookings b, customer c
left join grade g on b.chrggrade=g.grcode
left join person p on b.person=p.percode
where complete='Y' and invoiced='N'
and datemade between '2009-03-25' and '2009-03-31'
and c.custcode=b.cust
order by cust, person, tsref, stdt
Это приводит к ошибке SQL 1054, неизвестный столбец в b.chrggrade.Это потому, что он анализируется как
выберите b., с., g.*, p.perfname, p.persname из заказов b, (клиент c осталось присоединить оценку g к b.chrggrade=g.grcode ) осталось соединить person p с b.person=p.percode где complete ='Y' и invoiced='N' и datemade между '2009-03-25' и '2009-03-31' и c.custcode=b.cust заказ по cust, person, tsref, stdt
Я думаю.
Я уверен, что правильно расставленные скобки могут исправить это, но я в тупике.Я нашел ссылку на это изменение по адресу http://bugs.mysql.com/bug.php?id=13551, который показывает, как исправить простое соединение слева, но я все еще не могу решить это для этого запроса.Дэвид
Решение
Полностью прекратите использовать синтаксис запятой и будьте откровенны в своих операторах JOIN.Синтаксис запятой вынуждает вас поместить условие СОЕДИНЕНИЯ в предложение WHERE, которое может быть выполнено только после объединения ВЛЕВО / ВПРАВО, в зависимости от того, как оно анализируется.Использование явных объединений в любом случае делает запрос более читабельным.
...ИЗ t1, t2 ЛЕВОЕ СОЕДИНЕНИЕ t3 ВКЛЮЧЕНО (выражение) становится ...ИЗ t1 ВНУТРЕННЕЕ СОЕДИНЕНИЕ t2 ВКЛЮЧЕНО (выражение) ЛЕВОЕ СОЕДИНЕНИЕ t3 ВКЛЮЧЕНО (выражение)
Это также исправит ошибку, которую вы видите.Если в таблице бронирований нет chrggrade, то ошибку ничто не исправит.