Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
mysql变量赋值:如何强制赋值顺序?_Sql_Mysql_Variables - Fatal编程技术网

mysql变量赋值:如何强制赋值顺序?

mysql变量赋值:如何强制赋值顺序?,sql,mysql,variables,Sql,Mysql,Variables,由于mysql是一种声明性语言,我无法找到强制赋值变量顺序的方法 以这个查询为例: SET @v1=0; SET @v2=0; SELECT @v1, @v2 FROM MyTable table WHERE (@v1:=@v2) is not null AND (@v2:=2) is not null; 结果是: @v1 | @v2 --------- 2 | 2 这是因为mysql引擎在@v1之前解析@v2 我如何强制分配顺序得到以下结果: @v1 | @v2 ----

由于mysql是一种声明性语言,我无法找到强制赋值变量顺序的方法

以这个查询为例:

SET @v1=0;
SET @v2=0;

SELECT @v1, @v2 
FROM MyTable table 
WHERE (@v1:=@v2) is not null 
  AND (@v2:=2) is not null;
结果是:

@v1 | @v2
---------
 2  |  2
这是因为mysql引擎在@v1之前解析@v2

我如何强制分配顺序得到以下结果:

@v1 | @v2
---------
 0  |  2
编辑:这与以下问题不同:

这里有一个关于强制分配顺序的问题,而不是为什么结果不是预期的结果

更新: 使用左外联接时,结果也很奇怪:

SET @v1=0;

SELECT @v1
FROM Account other 
LEFT OUTER JOIN SimpleValue f_PC ON f_PC.accountId=other.id AND f_PC.refShortcut='PC'  
WHERE CASE WHEN (other.context='44') THEN (@v1:=@v1+1) ELSE null END
ORDER BY @v1 ASC
在本例中,查询返回60个结果,但@v1值为120


如果移除左侧外部联接,v1值为60。为什么?

正如你在回答另一个问题时所解释的那样,任何东西都不能保证有效

在您的特定情况下,将分配移动到查询的SELECT部分似乎有效:

SET @v1=0;
SET @v2=0;

SELECT (@v1:=@v2), (@v2:=2) 
FROM DUAL

select
语句中,该子句从左到右、从上到下,因此其结果与预期一致(MS Access使用相同的策略)。然而,在WHERE子句中,所有赌注都被取消,并选择了最佳过滤器。您可以利用CASE语句需要从左到右求值(保留表示顺序)这一事实来强制它


此强制将在任一分支中求值(并将2分配给@v2),但仅在第一次运行时,@v1:=@v2返回null,@v2变为2,与0进行比较,以获得总体
FALSE
。第二次,
@v1:=@v2[=2]
,和
(@v2:=2)
的结果是2(这是
正确的
)。

关于您的示例。

假设带有常量的操作在WHERE子句中的逻辑运算符中具有最高优先级

SET @v1=10;
SET @v2=20;
SELECT @v1, @v2 
FROM dual 
WHERE (@v2:=2) is not NULL AND (@v1:=@v2) is not NULL;
=======
@v1 @v2
2   2

SET @v1=30;
SET @v2=40;
SELECT @v1, @v2
FROM dual 
WHERE (@v1:=@v2) is not NULL AND (@v2:=2) is not NULL;
========
@v1 @v2
2   2
下面的例子清楚地证明了这一点。OR语句没有按照建议从左到右执行。OR运算符首先执行常量赋值操作

SET @v1=10;
SET @v2=20;
SELECT @v1, @v2 
FROM dual 
WHERE (@v2:=3) is not NULL OR (@v1:=@v2+1) is not NULL;
=========
@v1 @v2
10  3

SET @v1=30;
SET @v2=40;
SELECT @v1, @v2
FROM dual 
WHERE (@v1:=@v2+2) is not NULL OR (@v2:=4) is not NULL;
=========
@v1 @v2
30  4
关于赋值运算符和您的问题

在本例中,查询返回60个结果,但@v1值为120。如果我 移除左侧外部连接,v1值为60。为什么?

赋值运算符“:=”in WHERE子句是为查询中使用的每一行数据集计算出来的! 反之亦然,在SELECT子句中,为生成的行计算赋值运算符,以肯定地验证JOIN和WHERE子句中的检查

SET @v1=10;
SET @v2=20;
SELECT @v1, @v2 
FROM dual 
WHERE (@v2:=2) is not NULL AND (@v1:=@v2) is not NULL;
=======
@v1 @v2
2   2

SET @v1=30;
SET @v2=40;
SELECT @v1, @v2
FROM dual 
WHERE (@v1:=@v2) is not NULL AND (@v2:=2) is not NULL;
========
@v1 @v2
2   2

建议。尽量不要在WHERE子句中使用赋值运算符“:=”。在SELECT子句中使用赋值运算符。

可能重复您为什么再次问这个问题?这不是同一个问题,另一个问题是为什么我有这些结果?现在的问题是我如何才能取得预期的结果。由于StackOverflow不是一个论坛,我更喜欢打开另一个问题,因为我认为如果我只是编辑和转换这个问题,读过另一个问题的人不会回答它?@jerome-c Fair,感谢您更新此问题。我无法将其移动到select语句,因为我在where子句中使用了变量,select语句中的赋值仅在向客户端发送响应时计算。感谢您的回答,但它不会使用左外部联接运行。查看我的更新;)