首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >mysql变量赋值:如何强制赋值顺序?

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

Stack Overflow用户
提问于 2011-02-08 01:25:15
回答 3查看 1.1K关注 0票数 3

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

以这个查询为例:

代码语言:javascript
复制
SET @v1=0;
SET @v2=0;

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

结果是:

代码语言:javascript
复制
@v1 | @v2
---------
 2  |  2

这是因为mysql引擎在@v1之前解析了@v2。

如何强制赋值顺序产生此结果:

代码语言:javascript
复制
@v1 | @v2
---------
 0  |  2

编辑:这与以下问题不同:Variable assignment with mysql

这是一个关于强制赋值顺序的问题,而不是为什么结果不是预期的结果。

更新:使用left outer join时,结果也很奇怪:

代码语言:javascript
复制
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。为什么?

EN

回答 3

Stack Overflow用户

发布于 2011-02-08 04:21:25

select语句中,子句从左到右,从上到下,因此它的工作方式与预期一致(MS Access使用相同的策略)。然而,在WHERE子句中,所有的投注都是关闭的,并选择最佳的过滤器。您可以通过利用CASE语句需要从左到右求值(保持表示顺序)这一事实来强制它。

代码语言:javascript
复制
WHERE CASE WHEN (@v1:=@v2) is not null THEN (@v2:=2) ELSE (@v2:=2) = 0 END

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

票数 1
EN

Stack Overflow用户

发布于 2011-02-08 01:51:24

正如在回答你的另一个问题时所解释的那样,没有什么是可以保证工作的。

在您的特定情况下,将赋值移动到查询的选择部分似乎是可行的:

代码语言:javascript
复制
SET @v1=0;
SET @v2=0;

SELECT (@v1:=@v2), (@v2:=2) 
FROM DUAL
票数 0
EN

Stack Overflow用户

发布于 2019-12-31 21:49:40

关于你的例子的

在WHERE子句的逻辑运算符中,常量操作可能具有最高的优先级。

代码语言:javascript
复制
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运算符首先执行常量赋值操作。

代码语言:javascript
复制
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。为什么?

WHERE子句中的赋值操作符":=“是为查询中使用的数据集的每一行计算出来的!反之亦然,在SELECT子句中,计算出了结果行的赋值运算符,这肯定地验证了JOIN和WHERE子句中的检查。

Recommendation.尝试不要在WHERE子句中使用赋值运算符":=“。在SELECT子句中使用赋值运算符。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4924353

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档