MySQL中变量的意外行为

MySQL中变量的意外行为,mysql,Mysql,我只是有一个高级时刻。。。对我来说,这似乎违反直觉 考虑以下几点: DDLs 质疑 结果 +------+--------+------+--------+ | a_id | a_rank | b_id | b_rank | +------+--------+------+--------+ | a | 1 | a | 4 | | b | 2 | a | 4 | | c | 3 | a | 4 | |

我只是有一个高级时刻。。。对我来说,这似乎违反直觉

考虑以下几点:

DDLs

质疑

结果

+------+--------+------+--------+
| a_id | a_rank | b_id | b_rank |
+------+--------+------+--------+
| a    |      1 | a    |      4 |
| b    |      2 | a    |      4 |
| c    |      3 | a    |      4 |
| a    |      1 | b    |      5 |
| b    |      2 | b    |      5 |
| c    |      3 | b    |      5 |
| a    |      1 | c    |      6 |
| b    |      2 | c    |      6 |
| c    |      3 | c    |      6 |
+------+--------+------+--------+
预期结果

+------+--------+------+--------+
| a_id | a_rank | b_id | b_rank |
+------+--------+------+--------+
| a    |      1 | a    |      1 |
| b    |      2 | a    |      1 |
| c    |      3 | a    |      1 |
| a    |      1 | b    |      2 |
| b    |      2 | b    |      2 |
| c    |      3 | b    |      2 |
| a    |      1 | c    |      3 |
| b    |      2 | c    |      3 |
| c    |      3 | c    |      3 |
+------+--------+------+--------+
一模一样


那么,我遗漏了什么呢?

只需在查询的两侧使用不同的变量:

SELECT a.id a_id
     , a.rank a_rank
     , b.id b_id
     , b.rank b_rank
  FROM 
     ( SELECT id 
            , @i := @i+1 rank
         FROM my_table 
            , (SELECT @i:=0) vars
        ORDER
           BY id
     ) a
  JOIN 
     ( SELECT id 
            , @i1 := @i1+1 rank
         FROM my_table 
            , (SELECT @i1:=0) vars
        ORDER
           BY id
     ) b;

发生的情况是,初始化
@i
值的两个子查询首先运行,然后是查询的其余部分。无法保证何时运行子查询,因此这是允许的。

看起来在查询中不能两次使用同一个变量名。我可以看出,每次使用不同的变量名都可以解决问题,但子查询肯定应该首先根据自身的优缺点进行评估!!MySQL变量是全局连接。悲哀但正确。MySQL中同一select语句中同一变量的读写未定义。请参阅手册。Percona的人员通过检查实现代码表明,某些版本允许通过某些案例语句的使用来打破该规则。最后,有人在这件事上有建设性的话要说。不过,迟做总比不做强!我觉得奇怪的是,我以前从未注意到这一点,但我只是尝试在旧版本中运行相同的代码。同样的结果,所以一定是这样的:-$
+------+--------+------+--------+
| a_id | a_rank | b_id | b_rank |
+------+--------+------+--------+
| a    |      1 | a    |      1 |
| b    |      2 | a    |      1 |
| c    |      3 | a    |      1 |
| a    |      1 | b    |      2 |
| b    |      2 | b    |      2 |
| c    |      3 | b    |      2 |
| a    |      1 | c    |      3 |
| b    |      2 | c    |      3 |
| c    |      3 | c    |      3 |
+------+--------+------+--------+
SELECT a.id a_id
     , a.rank a_rank
     , b.id b_id
     , b.rank b_rank
  FROM 
     ( SELECT id 
            , @i := @i+1 rank
         FROM my_table 
            , (SELECT @i:=0) vars
        ORDER
           BY id
     ) a
  JOIN 
     ( SELECT id 
            , @i1 := @i1+1 rank
         FROM my_table 
            , (SELECT @i1:=0) vars
        ORDER
           BY id
     ) b;