任何人都可以发现我的错误,这应该是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)
答案 0 :(得分:4)
不要将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
之间没有看到任何加入条件,所以我假设您打算将其作为笛卡尔积?
有关连接的两种语法形式之间交互的更多详细信息,请参阅页面http://dev.mysql.com/doc/refman/5.0/en/join.html
上的加入MySQL 5.0.12中的处理更改部分重新评论:正如我所说,它与运营商优先级有关。如果您有一个带有FROM A, B JOIN C
的SQL查询,那么在它关注B JOIN C
之前它会评估A
- 包括分配表别名。因此,如果B JOIN C
的加入条件使用A
的表别名,则会收到错误,因为该别名尚不存在。
如果你反转它并运行B, A JOIN C
,那么当它评估A JOIN C
的连接条件时,A
的别名是可用的并且它有效(至少在这种情况下)。
但这是一个脆弱的解决方案,因为您可能还需要一个无法通过重新排序A
和B
来修复的查询。最好停止使用过时的连接语法和逗号。然后,任何连接表达式都可以访问所有表别名,并且在任何查询中都不会出现此问题。
答案 1 :(得分:1)
尝试在from子句中切换User
和Settings
:
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 `Setting` `s`, `Users` `u`
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)