我正在编写一个sql来获取数字列表的媒介(假设列表的长度是奇数(
set @r=0;
select S.num
from
(select num, case when num is not NULL then (@r:=@r+1) end as rowIndex
from T1
order by num) S
where rowIndex = ceil(@r/2)
这个查询有效,但是,我对我的子查询感到困惑。我的问题如下:如果我只是输入
select num, case when num is not NULL then (@r:=@r+1) end as rowIndex
from T1
我将有 2 列,第一列是原始顺序的数字原始列表,例如 10,1,3,11,5,4,19...第二列是行索引 1,2,3,4,....请注意,我想要的是首先按升序对原始列表进行排序,然后为每一行提供行索引。
我最初认为
select num, case when num is not NULL then (@r:=@r+1) end as rowIndex
from T1
order by num
将生成一个表,使得第一列是我的原始列表的排序版本,但第二列是索引集 [1,2,3,...] 的重新排列。因为我认为查询的顺序是:首先按照select num, case when num is not NULL then (@r:=@r+1) end as rowIndex from T1
的建议创建一个表,然后按num
列对这个表进行排序,因此,当对num
列进行排序时,rowIndex
列不应再是[1,2,3,...]。
但实际上,它似乎首先只是对num
列进行排序,然后添加行索引。换句话说,我发现无论我是否添加order by num
,第二列将始终是一个不错的行索引 [1,2,3,4,...]。为什么?
派生表(子查询(对num
列进行排序,并根据该顺序为每一行提供索引号。然后,外部查询重新使用计算的 @r 谷到达该有序序列中的中点(中位数(。
CREATE TABLE mytable( num NUMERIC(6,2) );
INSERT INTO mytable(num) VALUES (12.4); INSERT INTO mytable(num) VALUES (134.9); INSERT INTO mytable(num) VALUES (45.12); INSERT INTO mytable(num) VALUES (876.78); INSERT INTO mytable(num) VALUES (212.8); INSERT INTO mytable(num) VALUES (578.9);
set @r=0; select num, case when num is not NULL then (@r:=@r+1) end as rowIndex from mytable T1 order by num;
num | rowIndex -----: |-------: 12.40 | 1 45.12 | 2 134.90 | 3 212.80 | 4 578.90 | 5 876.78 | 6
set @r=0; select S.num from ( select num, case when num is not NULL then (@r:=@r+1) end as rowIndex from mytable T1 order by num ) S where rowIndex = ceil(@r/2);
| 数字 | |-----: | |134.90 |
在这里小提琴
但是,如果我们删除顺序,结果是不可预测的。
例如set @r=0; select num, case when num is not NULL then (@r:=@r+1) end as rowIndex from mytable T1 ;
num | rowIndex -----: |-------: 12.40 | 1 134.90 | 2 45.12 | 3 876.78 | 4 212.80 | 5 578.90 | 6
set @r=0; select S.num from ( select num, case when num is not NULL then (@r:=@r+1) end as rowIndex from mytable T1 ) S where rowIndex = ceil(@r/2);
| 数字 | |----: | |45.12 |
在这里小提琴
如果没有明确的 ORDER BY 子句,假设数字序列将根据需要排序是不安全的。它可能会发生,但你不能依赖它。