mysql 赋值问题

2022-09-27 15:36:34 +08:00
 su2018

如图所示

上面的 sql 没有赋值成功

下面的却可以

1704 次点击
所在节点    MySQL
4 条回复
lookStupiToForce
2022-09-27 17:32:24 +08:00
以下仅针对 5.7 之前的版本,之后的版本不确定

mysql 自定义变量的执行顺序是这样的,飘忽不定(可能按行可能按列,甚至还可能行列交叉赋值),不知道有谁能有确切的文档描述它的执行顺序 /执行规则
所以在不确定赋值顺序的情况下,在多个列里重复使用自定义变量是个危险的“未定义”行为
wxf666
2022-09-27 17:33:39 +08:00
1. 确实,本地可构建个类似的语句来复现,不知缘由:

*( V 站排版原因,开头有全角空格。若要复制运行,记得删除)*

```mysql
WITH
  nums(num) AS (
   VALUES ROW(1), ROW(2), ROW(3)
 )

SELECT @total, @total := sum(num)
FROM nums, (SELECT @total := 0) t
GROUP BY num;
```



2. 如果你只是想要『上一行的数据』,你可以使用*(连 SQLite 都支持的)*窗口函数 `LAG`:

```sql
WITH
  nums(num) AS (
   VALUES ROW(1), ROW(2), ROW(3) -- SQLite 写法:VALUES (1), (2), (3)
 )

SELECT num, LAG(num) OVER(ORDER BY num)
FROM nums;
```



3. 另外,[MySQL 官方文档]( https://dev.mysql.com/doc/refman/8.0/en/user-variables.html ) 很不推荐你图片中的用法:

- 除了 `SET` 语句外,不应在同一条语句内赋值和读取一个用户变量*( 5.7 版本文档:As a general rule, other than in SET statements, you should never assign a value to a user variable and read the value within the same statement )*

- 涉及用户变量的表达式的求值顺序未定义*( 8.0 版本文档:The order of evaluation for expressions involving user variables is undefined. For example, there is no guarantee that SELECT @a, @a:=@a+1 evaluates @a first and then performs the assignment )*

- 『在 `SELECT` 中使用 `:=` 为用户变量赋值』已被弃用,未来会移除*( 8.0 版本文档:Previous releases of MySQL made it possible to assign a value to a user variable in statements other than SET. This functionality is supported in MySQL 8.0 for backward compatibility but is subject to removal in a future release of MySQL )*
su2018
2022-09-29 17:14:08 +08:00
@lookStupiToForce 确实, 好像不同版本之间不一样, 在我的笔记本的顺序是错的, 在公司的电脑确实正确的 太魔幻了
su2018
2022-09-29 17:15:33 +08:00
@wxf666 谢谢啦, 我的 mysql 版本是 5.6 的 还不支持窗口函数 感觉 8.0 的好很多

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/883301

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX