Mysql 行编号(@i:=@i+1)无法按预期工作
该查询返回以下结果集:Mysql 行编号(@i:=@i+1)无法按预期工作,mysql,Mysql,该查询返回以下结果集: SET @i := 0; SELECT posts.post_id, members.member_joined, @i := @i + 1 FROM posts LEFT JOIN members ON posts.member_id = members.member_id WHERE posts.topic_id = 1 ORDER BY posts.post_created ASC; 正如你所看到的,由于一
SET @i := 0;
SELECT posts.post_id,
members.member_joined,
@i := @i + 1
FROM posts LEFT JOIN members
ON posts.member_id = members.member_id
WHERE posts.topic_id = 1
ORDER BY posts.post_created ASC;
正如你所看到的,由于一些我不知道的原因,数字2和3出现在结果集的最底部,而它们不应该出现
如果我注释掉members.member_joined行,如下所示:
现在的结果集与预期一致:
SET @i := 0;
SELECT posts.post_id,
-- members.member_joined,
@i := @i + 1
FROM posts LEFT JOIN members
ON posts.member_id = members.member_id
WHERE posts.topic_id = 1
ORDER BY posts.post_created ASC;
我就是受不了这件事。可能有什么问题?您的订单很可能导致计数关闭。。ORDER BY在查找select后执行,以便对您的计数进行重新排序。。尝试将其放入子查询中
+---------+--------------+
| post_id | @i := @i + 1 |
+---------+--------------+
| 1 | 1 |
+---------+--------------+
| 3 | 2 |
+---------+--------------+
| 4 | 3 |
+---------+--------------+
| 5 | 4 |
+---------+--------------+
| 14 | 5 |
+---------+--------------+
| 17 | 6 |
+---------+--------------+
| 35 | 7 |
+---------+--------------+
| 37 | 8 |
+---------+--------------+
| 42 | 9 |
+---------+--------------+
这样想吧。。选择要从表中拖动的位置。。。因此,任何具体要求都可以在WHERE中找到。。分组结束是在请求完成后,您正在更改返回的结果。。。这就是为什么订单会导致问题。。。当您将加入到选择中的成员包括进来时,它将返回计算结果,然后按日期重新排序
注:
MySQL对此非常清楚:
一般来说,您不应该为用户变量赋值
并读取同一语句中的值。你可能会得到
你期望的结果,但这不是保证。秩序
涉及用户变量的表达式的求值未定义且
可根据给定语句中包含的元素进行更改;
此外,不保证双方的订单相同
MySQL服务器的发布。在选择@a,@a:=@a+1,…,您可以
认为MySQL将首先计算@a,然后执行赋值
第二但是,更改语句(例如,通过添加
GROUPBY、HAVING或ORDERBY子句可能会导致MySQL选择
具有不同评估顺序的执行计划
很可能是您的订单导致了计数的减少。。ORDER BY在查找select后执行,以便对您的计数进行重新排序。。尝试将其放入子查询中
+---------+--------------+
| post_id | @i := @i + 1 |
+---------+--------------+
| 1 | 1 |
+---------+--------------+
| 3 | 2 |
+---------+--------------+
| 4 | 3 |
+---------+--------------+
| 5 | 4 |
+---------+--------------+
| 14 | 5 |
+---------+--------------+
| 17 | 6 |
+---------+--------------+
| 35 | 7 |
+---------+--------------+
| 37 | 8 |
+---------+--------------+
| 42 | 9 |
+---------+--------------+
这样想吧。。选择要从表中拖动的位置。。。因此,任何具体要求都可以在WHERE中找到。。分组结束是在请求完成后,您正在更改返回的结果。。。这就是为什么订单会导致问题。。。当您将加入到选择中的成员包括进来时,它将返回计算结果,然后按日期重新排序
注:
MySQL对此非常清楚:
一般来说,您不应该为用户变量赋值
并读取同一语句中的值。你可能会得到
你期望的结果,但这不是保证。秩序
涉及用户变量的表达式的求值未定义且
可根据给定语句中包含的元素进行更改;
此外,不保证双方的订单相同
MySQL服务器的发布。在选择@a,@a:=@a+1,…,您可以
认为MySQL将首先计算@a,然后执行赋值
第二但是,更改语句(例如,通过添加
GROUPBY、HAVING或ORDERBY子句可能会导致MySQL选择
具有不同评估顺序的执行计划
之前也有类似的问题。将左连接更改为内连接解决了此问题 详情如下:
之前也有类似的问题。将左连接更改为内连接解决了此问题 详情如下:
在记录已经处理和重新排序之后,我将如何重写查询,并对订单进行了很好的解释。+1。OP期望返回的结果取决于MySQL无法保证的操作顺序。让我们补充一点,这个答案中的查询之所以有效,是因为它使MySQL在执行其他操作之前先执行一些操作。但是文档给出了具体的警告,即我们观察到的用户定义变量的这种行为是不能保证的,即使是在查询重写的情况下也是如此。我将如何重写查询,并在记录已经处理和重新排序之后对order by进行了很好的解释。+1。OP期望返回的结果取决于MySQL无法保证的操作顺序。让我们补充一点,这个答案中的查询之所以有效,是因为它使MySQL在执行其他操作之前先执行一些操作。但是文档给出了具体的警告,即我们在用户定义变量中观察到的这种行为是不能保证的,即使在查询重写的情况下也是如此。您期望返回的结果取决于MySQL不能保证的操作顺序。查询的编写可能会有所不同,以使MySQL以不同的顺序执行操作。但是,即使重新编写了查询,MySQL参考手册也警告说,我们在使用用户定义变量时观察到的行为并不能得到保证。您期望返回的结果取决于MySQL不能保证的操作顺序。查询的编写可能会有所不同,以使MySQL以不同的顺序执行操作。但即使重新编写查询,MySQL Ref erence手册警告说,我们在使用用户定义变量时所观察到的行为是不能保证的。
SET @i := 0;
SELECT post_id, member_joined, @i := @i + 1
FROM
( SELECT p.post_id, m.member_joined
FROM posts p
LEFT JOIN members m ON p.member_id = m.member_id
WHERE p.topic_id = 1
ORDER BY p.post_created ASC
)t;