Mysql

时间:2017-07-04 00:45:30

标签: mysql sorting

我正在编写一个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列,第1列是原始顺序的原始数字列表,例如10,1,3,11,5,4,19 ......第2列是行索引,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,...]。为什么呢?

1 个答案:

答案 0 :(得分:1)

派生表(子查询)对您的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);
|    num |
| -----: |
| 134.90 |

dbfiddle here

如果我们删除订单,但结果不可预测。 e.g。

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);
|   num |
| ----: |
| 45.12 |

dbfiddle here

如果没有明确的ORDER BY子句,则假定数字序列将根据您的需要进行排序是不安全的。它可能会发生,但你不能依赖它。