最近我更新了一个服务器,从MySQL切换到MariaDB。现在有一个查询的行为不同了,我不明白为什么。请你指点我。
这是我目前的版本
mariadb --version
mariadb Ver 15.1 Distrib 10.6.11-MariaDB, for debian-linux-gnu (x86_64) using EditLine wrapper
实际的查询很长,但这里是我的问题的一个简化形式。我需要更新一个变量test
,在所有行都排序后,将为每一行更新该变量。
实际的更新更复杂,但在这里应该不重要:
@stockMass := @stockMass +
CASE
WHEN `u`.`context` = 'purchase' AND `u`.`status` != 'canceled' THEN `u`.`mass`
WHEN `u`.`context` = 'sale' AND `u`.`status` != 'canceled' THEN -`u`.`mass`
WHEN `u`.`context` = 'massAdjustment' THEN `u`.`mass`
WHEN `u`.`context` = 'splitIn' THEN `u`.`mass`
WHEN `u`.`context` = 'splitOut' THEN -`u`.`mass`
ELSE 0
END AS `stock`
SET @test := 0;
SELECT
*,
@test := @test + 1 AS `test`
FROM (
SELECT
`g_sales`.`sale`,
`g_sales`.`date`
FROM
`g_sales`
ORDER BY
`g_sales`.`date`
) AS `t` ORDER BY `t`.`date`;
导致
+------+------------+------+
| sale | date | test |
+------+------------+------+
| 106 | 2019-06-19 | 2703 |
| 85 | 2019-10-11 | 2685 |
| 81 | 2019-11-12 | 2681 |
| 96 | 2019-12-09 | 2695 |
| 104 | 2020-03-26 | 2701 |
| 87 | 2020-04-06 | 2687 |
| 94 | 2020-05-15 | 2693 |
| 107 | 2020-05-18 | 2704 |
| 98 | 2020-05-28 | 2697 |
| 103 | 2020-05-28 | 2700 |
| ... | .......... | .... |
+------+------------+------+
在MySQL中,测试从1开始,每行增加1。在内部SELECT中添加一个限制,在MariaDB中得到了类似的结果。
SET @test := 0;
SELECT
*,
@test := @test + 1 AS `test`
FROM (
SELECT
`g_sales`.`sale`,
`g_sales`.`date`
FROM
`g_sales`
ORDER BY
`g_sales`.`date`
LIMIT 10 OFFSET 0
) AS `t`;
这导致
+------+------------+------+
| sale | date | test |
+------+------------+------+
| 106 | 2019-06-19 | 1 |
| 85 | 2019-10-11 | 2 |
| 81 | 2019-11-12 | 3 |
| 96 | 2019-12-09 | 4 |
| 104 | 2020-03-26 | 5 |
| 87 | 2020-04-06 | 6 |
| 94 | 2020-05-15 | 7 |
| 107 | 2020-05-18 | 8 |
| 98 | 2020-05-28 | 9 |
| 103 | 2020-05-28 | 10 |
+------+------------+------+
如何在MariaDB中获得此结果而不对内部SELECT添加限制?
为什么我在加上LIMIT时会得到这个结果?
1条答案
按热度按时间6uxekuva1#
我在从MariaDB V10.4.12更改到V10.6.8时遇到了类似的问题(参见here)。
我帖子里的评论者提到
MySQL不赞成在SELECT中分配@variables。
我不确定这是否正确,但考虑到顺序,在
SELECT
中定义用户定义的变量似乎没有很好地定义。例如MySQL manual:未定义涉及用户变量的表达式的计算顺序。例如,不能保证SELECT @a,@a:=@a+1首先计算@a,然后执行赋值。
MariaDB manual:
在同一语句中读取用户定义的变量并设置其值是不安全的(除非命令是SET),因为这些操作的顺序未定义。
你可以使用Windows function,例如
ROW_NUMBER
,但正如你提到的,如果你有复杂的条件,它就不起作用。在
SELECT
中使用和定义用户定义变量的好处是,它是一种强大的方法,可以使用您需要的任何条件来定义行:由于MariaDB/MySQL的新版本,这种查询似乎不起作用。这是皮蒂,我想知道为什么会这样,有什么替代品。