最近将数据库从MySQL 4升级到MySQL 5.以下查询现已破坏:
SELECT COUNT(*) FROM Customer, Product INNER JOIN Orders
ON (Customer.Email = Orders.Email)
WHERE NOT (Product.Flags & 8) AND
Customer.CustomerNumber = Product.CustomerNumber AND
Truncate(Orders.ProductId/10, 0) = Truncate(Product.ProductId/10, 0)
收到以下错误:
#1054 - Unknown column 'Customer.Email' in 'on clause'
我没有写这个查询,我不是SQL大师,但我猜测可能是ANSI-89 / ANSI-92样式连接的混合,可能会出现某种优先级问题上。
您能否解释错误,描述此查询的错误,以及如何正确指定联接?
答案 0 :(得分:6)
正如JOIN
Syntax所述:
加入MySQL 5.0.12中的处理更改
[ deletia ]以下列表提供了有关旧版本中当前联接处理与联接处理的几种效果的更多详细信息。术语“先前”表示“在MySQL 5.0.12之前。”
[ deletia ]
以前,逗号运算符(
,
)和JOIN
都具有相同的优先级,因此连接表达式t1, t2 JOIN t3
被解释为((t1, t2) JOIN t3)
。现在JOIN
具有更高的优先级,因此表达式被解释为(t1, (t2 JOIN t3))
。此更改会影响使用ON
子句的语句,因为该子句只能引用连接操作数中的列,并且优先级的更改会更改这些操作数的解释。示例:
CREATE TABLE t1 (i1 INT, j1 INT); CREATE TABLE t2 (i2 INT, j2 INT); CREATE TABLE t3 (i3 INT, j3 INT); INSERT INTO t1 VALUES(1,1); INSERT INTO t2 VALUES(1,1); INSERT INTO t3 VALUES(1,1); SELECT * FROM t1, t2 JOIN t3 ON (t1.i1 = t3.i3);
以前,
SELECT
是合法的,因为t1,t2
隐式分组为(t1,t2)
。现在JOIN
优先,因此ON
子句的操作数为t2
和t3
。由于t1.i1
不是任一操作数中的列,因此结果为Unknown column 't1.i1' in 'on clause'
错误。要允许处理连接,请使用括号将前两个表显式分组,以便ON
子句的操作数为(t1,t2)
和t3
:SELECT * FROM (t1, t2) JOIN t3 ON (t1.i1 = t3.i3);
或者,避免使用逗号运算符并改为使用
JOIN
:SELECT * FROM t1 JOIN t2 JOIN t3 ON (t1.i1 = t3.i3);
此更改也适用于将逗号运算符与
INNER JOIN
,CROSS JOIN
,LEFT JOIN
和RIGHT JOIN
混合在一起的语句,所有这些语句现在都具有比逗号更高的优先级操作