Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Wie kann dieses SQL falsch sein? Was sehe ich nicht?

Mischen Sie die Join-Syntax im „Komma-Stil“ von SQL-89 nicht mit SQL-92 JOIN Syntax. Es gibt subtile Probleme mit dem Vorrang dieser beiden Arten von Join-Vorgängen.

In Ihrem Fall ist die Folge, dass die Join-Bedingung LEFT JOIN ausgewertet wird vor dem u Tabellenalias existiert. Deshalb weiß es nicht, was u.usr_auto_key ist ist.

Sie können dieses Problem beheben, indem Sie JOIN verwenden Syntax für alle Joins:

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)

Ich habe keine Join-Bedingung zwischen u gesehen und s in Ihrer Anfrage, also nehme ich an, dass Sie beabsichtigen, dass dies ein kartesisches Produkt ist?

Weitere Einzelheiten zur Interaktion zwischen den beiden Syntaxformen für Join finden Sie im Abschnitt Änderungen bei der Join-Verarbeitung in MySQL 5.0.12 auf der Seite http://dev.mysql.com/doc/ refman/5.0/en/join.html

Zu Ihrem Kommentar:Wie gesagt, es hat mit der Operatorpriorität zu tun. Wenn Sie eine SQL-Abfrage mit FROM A, B JOIN C haben dann wertet es B JOIN C aus bevor es sich um A kümmert -- dazu gehört auch das Zuweisen von Tabellenaliasen. Wenn also Ihre Join-Bedingung für B JOIN C verwendet den Tabellenalias für A Sie erhalten eine Fehlermeldung, weil dieser Alias ​​noch nicht existiert.

Wenn Sie es umkehren und B, A JOIN C ausführen dann, wenn es die Join-Bedingung für A JOIN C auswertet der Alias ​​für A verfügbar ist und funktioniert (zumindest in diesem Fall).

Dies ist jedoch eine fragile Lösung, da Sie möglicherweise auch eine Abfrage benötigen, die nicht einfach durch Neuordnen von A behoben werden kann und B . Es ist besser, die veraltete Join-Syntax mit Kommas einfach nicht mehr zu verwenden. Dann hat jeder Join-Ausdruck Zugriff auf alle Ihre Tabellen-Aliasnamen und Sie werden dieses Problem in keiner Abfrage haben.