sql >> Databáze >  >> RDS >> Mysql

Jak může být tento SQL špatný? co nevidím?

Nesměšujte syntaxi spojení SQL-89 "ve stylu čárky" s SQL-92 JOIN syntax. Existují drobné problémy s předností těchto dvou typů operací spojení.

Ve vašem případě to má za následek, že vyhodnocuje podmínku spojení LEFT JOIN před u alias tabulky existuje. Proto neví, co je u.usr_auto_key je.

Tento problém můžete napravit pomocí JOIN syntaxe pro všechna spojení:

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)

Neviděl jsem žádnou podmínku spojení mezi u a s ve vašem dotazu, takže předpokládám, že to zamýšlíte jako kartézský produkt?

Další podrobnosti o interakci mezi dvěma formuláři syntaxe pro spojení naleznete v části Join Processing Changes in MySQL 5.0.12 na stránce http://dev.mysql.com/doc/ refman/5.0/en/join.html

K vašemu komentáři:Jak jsem řekl, souvisí to s prioritou operátora. Pokud máte dotaz SQL s FROM A, B JOIN C pak vyhodnotí B JOIN C než věnuje pozornost A -- to zahrnuje přiřazení aliasů tabulek. Takže pokud je vaše podmínka připojení pro B JOIN C používá alias tabulky pro A zobrazí se chyba, protože tento alias ještě neexistuje.

Pokud to otočíte a spustíte B, A JOIN C poté, když vyhodnotí podmínku spojení pro A JOIN C alias pro A je k dispozici a funguje (alespoň v tomto případě).

Toto je však křehké řešení, protože možná budete potřebovat také dotaz, který nelze opravit pouhým přeuspořádáním A a B . Je lepší přestat používat zastaralou syntaxi spojení s čárkami. Pak má jakýkoli spojovací výraz přístup ke všem aliasům vašich tabulek a tento problém už nikdy nebudete mít v žádném dotazu.



  1. Metoda sběru:Funkce PRIOR &NEXT v databázi Oracle

  2. 4 Funkce pro vrácení měsíce z data v MariaDB

  3. mysql do php do xml zobrazuje prázdný věk

  4. Proč vůbec používat *DB.exec() nebo připravené příkazy v Golangu?