Mysql(左)如何解释这种行为?

Mysql(左)如何解释这种行为?,mysql,sql,Mysql,Sql,与左连接 SET @foo:=0; SELECT @foo FROM test t1 LEFT JOIN test t2 ON t2.id=t1.id AND (@foo:=@foo+1); SET @foo:=0; SELECT @foo FROM test t1 JOIN test t2 ON t2.id=t1.id AND (@foo:=@foo+1); 打印0,0,0,0,0,0,0,0 但使用JOIN SET @foo:=0; SELECT @foo FROM

与左连接

SET @foo:=0;
SELECT @foo 
FROM test t1 
  LEFT JOIN test t2 ON t2.id=t1.id AND (@foo:=@foo+1);
SET @foo:=0;
SELECT @foo 
FROM test t1 
   JOIN test t2 ON t2.id=t1.id AND (@foo:=@foo+1);
打印0,0,0,0,0,0,0,0

但使用JOIN

SET @foo:=0;
SELECT @foo 
FROM test t1 
  LEFT JOIN test t2 ON t2.id=t1.id AND (@foo:=@foo+1);
SET @foo:=0;
SELECT @foo 
FROM test t1 
   JOIN test t2 ON t2.id=t1.id AND (@foo:=@foo+1);
打印1,2,3,4,5,6

有人知道吗?谢谢


UPD。此查询生成除@foo value以外的相同行。也许,mysql引擎不会检查第二个条件,如果第一个条件返回false,则按顺序检查第一个条件是否返回false,这在左连接中是可能的。您提到过从表t1中选择一些附加数据吗?
这两种操作之间的区别可能是左连接的行为。LEFT JOIN尝试根据规则加入。它从数据集左侧拾取一条记录,并尝试从数据集右侧连接其他数据。如果不存在匹配项,则数据集righthand的所有列都将设置为NULL并合并。普通联接跳过无法进行联接的记录

id
--
1
2
3
4

左连接拾取记录a,尝试左连接其他记录。每个ID与a的ID不同的记录都会导致连接失败。但是LEFT JOIN不会跳过这些记录,因为所需的左侧数据(记录a)可用。因此,结果记录将被连接记录的null填充,并且foo不会增加。

会话变量的赋值在
ON
子句中不起作用

您看到@foo因内部联接而递增的原因是优化器以以下方式运行您的查询:

SET @foo:=0;
SELECT @foo 
FROM test t1 
   JOIN test t2 
   WHERE t2.id=t1.id AND (@foo:=@foo+1);
使用
EXPLAIN SELECT…
您应该在额外列中看到
使用where

您还可以使用
EXPLAIN EXTENDED SELECT…
,然后使用
SHOW WARNINGS
查看优化器如何准确地运行查询

在您的情况下,
LEFT JOIN
查询的运行方式与编写时完全相同,对于这种类型的连接,您可以在
ON
WHERE
中的相同条件下获得不同的结果

如果要为
左连接增加@foo,请使用:

SET @foo:=0;
SELECT @foo 
FROM test t1 
  LEFT JOIN test t2 ON t2.id=t1.id
  WHERE @foo:=@foo+1

这只能应用于或惰性条件,但不能应用于和。必须计算原因in和两个运算符,以确定结果是否相同。因此,我假设两个示例中的测试表是相同的。Ups。我是noob)你是对的),如果左操作符为false,如果选择@foo,则可以跳过右计算;在第一次选择之后,内部联接和左联接情况下的输出是什么?尽管有上述输出,我希望它们都是相同的。您是否比较了这两个
EXPLAIN SELECT
s?我不知道这有什么帮助,但这本身就是一个有趣的问题。但是,您可以执行
选择@foo:=@foo+1
来解决此问题。添加其他数据会产生相同的结果。例如SELECT*,@foo产生相同的结果。另一个有趣的事情是这两个查询产生相同的结果,除了@foo value)