MariaDB中用户变量计数器的混乱排序

v2g6jxz6  于 2023-05-17  发布在  其他
关注(0)|答案(1)|浏览(376)

最近我更新了一个服务器,从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时会得到这个结果?

6uxekuva

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中使用和定义用户定义变量的好处是,它是一种强大的方法,可以使用您需要的任何条件来定义行:

SELECT @x := IF(id = @previous_id AND @y=1 AND other conditions, 1,100)
     , @previous_id := id
     , @y := something
     , ....

由于MariaDB/MySQL的新版本,这种查询似乎不起作用。这是皮蒂,我想知道为什么会这样,有什么替代品。

相关问题