Mysql
 sql >> база данни >  >> RDS >> Mysql

Как може този SQL да е грешен? Какво не виждам?

Не смесвайте SQL-89 синтаксис на присъединяване в стил „запетая“ с SQL-92 JOIN синтаксис. Има фини проблеми с предимството на тези два типа операции за свързване.

Във вашия случай последствието е, че оценява условието за присъединяване LEFT JOIN преди u съществува псевдоним на таблицата. Ето защо то не знае какво u.usr_auto_key е.

Можете да коригирате този проблем, като използвате JOIN синтаксис за всички съединения:

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)

Не видях никакво условие за присъединяване между u и s във вашето запитване, така че предполагам, че възнамерявате това да бъде декартов продукт?

За повече подробности относно взаимодействието между двете синтактични форми за присъединяване, вижте раздела Промени в обработката на присъединяване в MySQL 5.0.12 на страницата http://dev.mysql.com/doc/ refman/5.0/en/join.html

Относно вашия коментар:Както казах, това е свързано с приоритета на оператора. Ако имате SQL заявка с FROM A, B JOIN C след това оценява B JOIN C преди да обърне внимание на A -- което включва присвояване на псевдоними на таблици. Така че, ако вашето условие за присъединяване за B JOIN C използва псевдонима на таблицата за A получавате грешка, защото този псевдоним все още не съществува.

Ако го обърнете и стартирате B, A JOIN C след това докато оценява условието за присъединяване за A JOIN C псевдонимът за A е наличен и работи (поне в този случай).

Но това е крехко решение, защото може да се нуждаете и от заявка, която не може да бъде коригирана само чрез пренареждане на A и B . По-добре е просто да спрете да използвате остарелия синтаксис на присъединяване със запетаи. Тогава всеки израз за присъединяване има достъп до всичките ви псевдоними на таблици и никога няма да имате този проблем в нито една заявка.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да промените часовата зона на MySQL във връзка с база данни с помощта на Java?

  2. Дублиране, копиране или архивиране на таблици в MySQL, MariaDB, Oracle, PostgreSQL, DB2 и SQLite със Създаване на таблица като SQL

  3. Проблем с първоначалното разрешение в mysql

  4. „Свържете“ приложение на rails към вече съществуваща MySQL DB?

  5. Кога да затворите MySQL връзката с помощта на node-mysql?