sql >> Database teknologi >  >> RDS >> Mysql

Hvordan kan denne SQL være forkert? Hvad ser jeg ikke?

Bland ikke SQL-89 "komma-stil" joinsyntaks med SQL-92 JOIN syntaks. Der er subtile problemer med forrangen af ​​disse to typer join-operationer.

I dit tilfælde er konsekvensen, at det evaluerer join-betingelsen LEFT JOIN før u tabelalias findes. Det er derfor, den ikke ved hvad u.usr_auto_key er.

Du kan rette dette problem ved at bruge JOIN syntaks for alle joinforbindelser:

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)

Jeg så ikke nogen sammenføjningsbetingelse mellem u og s i din forespørgsel, så jeg antager, at du har til hensigt at være et kartesisk produkt?

For flere detaljer om interaktionen mellem de to syntaksformer for join, se afsnittet Join Processing Changes in MySQL 5.0.12 på siden http://dev.mysql.com/doc/ refman/5.0/da/join.html

Vedrørende din kommentar:Som sagt har det at gøre med operatørens forrang. Hvis du har en SQL-forespørgsel med FROM A, B JOIN C derefter evaluerer den B JOIN C før den lægger mærke til A -- det inkluderer tildeling af tabelaliaser. Så hvis din deltagelsesbetingelse for B JOIN C bruger tabelaliasset for A du får en fejl, fordi det alias ikke eksisterer endnu.

Hvis du vender det om og kører B, A JOIN C derefter som den evaluerer join-betingelsen for A JOIN C aliaset for A er tilgængelig, og den virker (i hvert fald i dette tilfælde).

Men dette er en skrøbelig løsning, fordi du måske også har brug for en forespørgsel, der ikke kan rettes bare ved at omarrangere A og B . Det er bedre bare at stoppe med at bruge den forældede joinsyntaks med kommaer. Så har ethvert join-udtryk adgang til alle dine tabelaliasser, og du vil aldrig have dette problem i nogen forespørgsel.



  1. Sådan vælger du den første række i hver gruppe efter gruppe

  2. Hvordan bruger man PHP-streng i mySQL LIKE-forespørgsel?

  3. PostgreSQL:Den alsidige INSERT

  4. Sådan tilføjer du dage til en dato i T-SQL