一千萬個為什麽

搜索

這個SQL怎麽會出錯?我沒看到什麽?

任何人都可以發現我的錯誤,這應該是SQL中的合法查詢不應該嗎?

ON子句中的未知列u.usr_auto_key

這是數據庫架構:

User: (usr_auto_key, name, etc...)
Setting: (set_auto_key, name etc..)
User_Setting: (usr_auto_key, set_auto_key, value)

這是查詢......

        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`, `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)

最佳答案

不要將SQL-89“逗號樣式”連接語法與SQL-92 JOIN 語法混合使用。這兩種類型的連接操作的優先級存在細微問題。

在您的情況下,結果是它在 u 表別名存在之前評估連接條件 LEFT JOIN 。這就是為什麽它不知道 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)

我在查詢中沒有看到 us 之間的任何連接條件,所以我假設您打算將其作為笛卡爾積?


For more details on the interaction between the two syntax forms for join, see the section Join Processing Changes in MySQL 5.0.12 on the page http://dev.mysql.com/doc/refman/5.0/en/join.html


重新評論:正如我所說,它與運算符優先級有關。如果你有一個帶有 FROM A,B JOIN C 的SQL查詢,那麽在它關註 A 之前它會評估 B JOIN C - 包括分配表別名。因此,如果 B JOIN C 的連接條件使用 A 的表別名,則會出現錯誤,因為該別名尚不存在。

如果你反轉並運行 B,A JOIN C ,那麽在評估 A JOIN C 的連接條件時,可以使用 A 的別名,它起作用(至少在這種情況下)。

但這是一個脆弱的解決方案,因為您可能還需要一個無法通過重新排序 AB 來修復的查詢。最好停止使用過時的連接語法和逗號。然後任何連接表達式都可以訪問所有表別名,並且在任何查詢中都不會出現此問題。

轉載註明原文: 這個SQL怎麽會出錯?我沒看到什麽?