Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Como esse SQL pode estar errado? O que eu não estou vendo?


Não misture a sintaxe de junção SQL-89 "estilo vírgula" com SQL-92 JOIN sintaxe. Existem problemas sutis com a precedência desses dois tipos de operações de junção.

No seu caso, a consequência é que está avaliando a condição de junção LEFT JOIN antes do u alias de tabela existe. É por isso que não sabe o que u.usr_auto_key é.

Você pode corrigir esse problema usando JOIN sintaxe para todas as junções:
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)

Não vi nenhuma condição de junção entre u e s em sua consulta, então suponho que você pretende que este seja um produto cartesiano?

Para obter mais detalhes sobre a interação entre os dois formulários de sintaxe para junção, consulte a seção Join Processing Changes in MySQL 5.0.12 na página http://dev.mysql.com/doc/ refman/5.0/en/join.html

Re seu comentário:Como eu disse, tem a ver com a precedência do operador. Se você tiver uma consulta SQL com FROM A, B JOIN C então ele avalia o B JOIN C antes de prestar atenção em A -- que inclui a atribuição de aliases de tabela. Portanto, se sua condição de junção para B JOIN C usa o alias de tabela para A você recebe um erro porque esse alias ainda não existe.

Se você reverter e executar B, A JOIN C então, como ele avalia a condição de junção para A JOIN C o alias para A está disponível e funciona (pelo menos neste caso).

Mas esta é uma solução frágil, porque você também pode precisar de uma consulta que não pode ser corrigida apenas reordenando A e B . É melhor parar de usar a sintaxe de junção desatualizada com vírgulas. Então qualquer expressão de junção tem acesso a todos os seus aliases de tabela e você nunca terá esse problema em nenhuma consulta.