为什么MySQL4中的这个查询在MySQL5中不起作用?

Mar*_*rkS 1 mysql

最近将数据库从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)
Run Code Online (Sandbox Code Playgroud)

收到以下错误:

#1054 - Unknown column 'Customer.Email' in 'on clause' 
Run Code Online (Sandbox Code Playgroud)

我没有写这个查询,我不是SQL大师,但我猜测可能是ANSI-89/ANSI-92样式连接的混合,并且可能存在某种优先级问题.

你能解释一下这个错误,描述这个查询有什么问题,以及如何正确指定连接?

egg*_*yal 6

JOIN语法下所述:

 加入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);
    
    Run Code Online (Sandbox Code Playgroud)

    以前,SELECT由于隐含的t1,t2as 分组,这是合法的(t1,t2).现在JOIN优先,因此该ON子句的操作数是t2t3.因为t1.i1不是任何一个操作数中的列,结果是Unknown column 't1.i1' in 'on clause'错误.要允许处理连接,请使用括号显式地对前两个表进行分组,以使ON子句的操作数为(t1,t2)t3:

    SELECT * FROM (t1, t2) JOIN t3 ON (t1.i1 = t3.i3);
    
    Run Code Online (Sandbox Code Playgroud)

    或者,避免使用逗号运算符并使用JOIN:

    SELECT * FROM t1 JOIN t2 JOIN t3 ON (t1.i1 = t3.i3);
    
    Run Code Online (Sandbox Code Playgroud)

    这种变化也适用于与混合逗号操作语句INNER JOIN,CROSS JOIN,LEFT JOIN,并且RIGHT JOIN,所有这些现在已经比逗号运算符优先级越高.