MariaDB 10.1.18
表P(id int AUTO_INCREMENT,rownum int,code int,s int,PRIMARY KEY(id));
select id, rownum, code, s from P order by id;
+----+--------+------+------+
| id | rownum | code | s |
+----+--------+------+------+
| 1 | 1 | 5 | 1 |
| 2 | 2 | 5 | 1 |
| 3 | 3 | 5 | 1 |
| 4 | 4 | 5 | 1 |
| 5 | 5 | 5 | 1 |
| 6 | 6 | 7 | 1 |
| 7 | 7 | 7 | 1 |
| 8 | 8 | 7 | 1 |
| 9 | 9 | 7 | 1 |
| 10 | 10 | 7 | 1 |
+----+--------+------+------+
问题:以下2个查询非常相似:第一个查询加入id,第二个加入rownum; id和rownum列具有相同的值(参见上表),但查询结果在计算列N中有所不同:
查询1:加入id列
SELECT P.id, P.rownum, P2.s,
IF(P2.s IS NULL, @val:=@val+1, @val) as N
FROM P CROSS JOIN (SELECT @val:=0) init
LEFT JOIN P P2
ON (P.id+1=P2.id AND P.s=1 AND P2.s=1 AND P.code = P2.code)
ORDER BY P.id;
+----+--------+------+------+
| id | rownum | s | N |
+----+--------+------+------+
| 1 | 1 | 1 | 0 |
| 2 | 2 | 1 | 0 |
| 3 | 3 | 1 | 0 |
| 4 | 4 | 1 | 0 |
| 5 | 5 | NULL | 1 |
| 6 | 6 | 1 | 1 |
| 7 | 7 | 1 | 1 |
| 8 | 8 | 1 | 1 |
| 9 | 9 | 1 | 1 |
| 10 | 10 | NULL | 2 |
+----+--------+------+------+
查询2:加入rownum列
SELECT P.id, P.rownum, P2.s,
IF(P2.s IS NULL, @val:=@val+1, @val) as N
FROM P CROSS JOIN (SELECT @val:=0) init
LEFT JOIN P P2
ON (P.rownum+1=P2.rownum AND P.s=1 AND P2.s=1 AND P.code = P2.code)
ORDER BY P.id;
+----+--------+------+------+
| id | rownum | s | N |
+----+--------+------+------+
| 1 | 1 | 1 | 0 |
| 2 | 2 | 1 | 0 |
| 3 | 3 | 1 | 0 |
| 4 | 4 | 1 | 0 |
| 5 | 5 | NULL | 1 |
| 6 | 6 | 1 | 0 |
| 7 | 7 | 1 | 0 |
| 8 | 8 | 1 | 0 |
| 9 | 9 | 1 | 0 |
| 10 | 10 | NULL | 2 |
+----+--------+------+------+
答案 0 :(得分:0)
正如MariaDB knowledge base和MySQL manual中明确记录的那样,除非此语句为SET
,否则不应读取用户定义的变量并在同一语句中设置其值。对于其他陈述,它是不安全的,并且结果不能保证,正如您的示例清楚地证明的那样。
附加说明:您在问题中谈论的变量通常被称为“用户定义变量”或“用户变量”,而不是“系统变量”,“全局变量”和“会话”变量',每个变量都意味着系统定义的变量,无论是全部变量还是仅限于给定范围。