Nie mieszaj składni sprzężenia SQL-89 „w stylu przecinka” z SQL-92 JOIN
składnia. Istnieją subtelne problemy z pierwszeństwem tych dwóch typów operacji łączenia.
W twoim przypadku konsekwencją jest to, że ocenia warunek złączenia LEFT JOIN
przed u
alias tabeli istnieje. Dlatego nie wie, co u.usr_auto_key
jest.
Możesz rozwiązać ten problem, używając JOIN
składnia dla wszystkich złączeń:
SELECT
`u`.`usr_auto_key` AS `u__usr_auto_key`,
`s`.`set_auto_key` AS `s__set_auto_key`,
`u2`.`usr_auto_key` AS `u2__usr_auto_key`,
`u2`.`set_auto_key` AS `u2__set_auto_key`,
`u2`.`value` AS `u2__value`
FROM `User` `u` JOIN `Setting` `s`
LEFT JOIN `User_Setting` `u2` ON `u`.`usr_auto_key` = `u2`.`usr_auto_key`
WHERE (`s`.`sct_auto_key` = 1 AND `u`.`usr_auto_key` = 1 AND admin_property is null)
Nie widziałem żadnego warunku połączenia między u
i s
w zapytaniu, więc zakładam, że ma to być produkt kartezjański?
Aby uzyskać więcej informacji na temat interakcji między dwoma formularzami składni przy łączeniu, zobacz sekcję Zmiany przetwarzania łączenia w MySQL 5.0.12 na stronie http://dev.mysql.com/doc/ refman/5.0/pl/dołącz.html
Odnieś się do twojego komentarza:Jak powiedziałem, ma to związek z pierwszeństwem operatorów. Jeśli masz zapytanie SQL z FROM A, B JOIN C
następnie ocenia B JOIN C
zanim zwróci jakąkolwiek uwagę na A
-- która obejmuje przypisywanie aliasów tabel. Więc jeśli twój warunek dołączenia do B JOIN C
używa aliasu tabeli dla A
pojawia się błąd, ponieważ ten alias jeszcze nie istnieje.
Jeśli odwrócisz to i uruchomisz B, A JOIN C
następnie, gdy ocenia warunek złączenia dla A JOIN C
alias dla A
jest dostępny i działa (przynajmniej w tym przypadku).
Ale jest to delikatne rozwiązanie, ponieważ możesz również potrzebować zapytania, którego nie można naprawić, zmieniając tylko kolejność A
i B
. Lepiej po prostu przestać używać przestarzałej składni łączenia z przecinkami. Wtedy każde wyrażenie sprzężenia będzie miało dostęp do wszystkich aliasów tabeli i nigdy nie będziesz mieć tego problemu w żadnym zapytaniu.