Mysql实战之求出缺失范围
1.需求
求出缺失范围
2.示例
根据表中某个变化字段,求出变化字段的缺失范围。如下给出一个例子:
下面是一个表x,其中的数据如下:
mysql> select * from x;
+------+
| a    |
+------+
|    3 |
|    4 |
|    5 |
|    6 |
|  100 |
|  101 |
|  102 |
|  105 |
|  106 |
|  107 |
+------+
10 rows in set (0.03 sec)其中的缺失范围就是:7-99,103-104。
3.代码一
- sql 1
 下面这个SQL是用于查找不连续的值。【如果x1.a+1=x2.a,那么说明x1.a是连续的,反之不连续。因为这里使用的是not exists,所以就是不连续的,可以查看得到最后的结果集就是6,102,107】
select a
from x as x1
where not exists 
(
  select *
  from x as x2
  where x1.a + 1 = x2.a
);执行结果如下:
+------+
| a    |
+------+
|    6 |
|  102 |
|  107 |
+------+
3 rows in set (0.00 sec)- sql 2
 因为我们需要求“缺失序列”,所以由上面的结果集可知,6,102,107均非缺失值,但是将其分别+1就得到了缺失值。但是又因为107+1已经超过了表中的最大值,所以丢弃。那么可得到下述的SQL:
select a+1 as start_range
from x as x1
where not exists 
(
  select *
  from x as x2
  where x1.a + 1 = x2.a
)
and a< (select max(a) from x);执行结果如下:
+-------------+
| start_range |
+-------------+
|           7 |
|         103 |
+-------------+
2 rows in set (0.00 sec)- sql 3
 因为要得到一个缺失序列,肯定要有缺失字段的结束范围,所以再找出结束值。【这里的结束值就是大于连续值的最小值-1】
select 
a+1 as start_range
,(
  select 
  min(a) -1 
  from x as x3
  where x3.a > x1.a
) as end_range
from x as x1
where not exists 
(
  select a
  from x as x2
  where x1.a + 1 = x2.a
)
and a< (select max(a) from x);执行结果如下:
+-------------+-----------+
| start_range | end_range |
+-------------+-----------+
|           7 |        99 |
|         103 |       104 |
+-------------+-----------+
2 rows in set (0.00 sec)代码二
上述只是一个普通的解决方案,如果追求效率,可以参考下面这个更好的SQL:
select a as cur,
(
  select 
  min(a) 
  from x as x1
  where x1.a > x2.a
) as next
from x as x2;执行结果如下:
+------+------+
| cur  | next |
+------+------+
|    3 |    4 |
|    4 |    5 |
|    5 |    6 |
|    6 |  100 |
|  100 |  101 |
|  101 |  102 |
|  102 |  105 |
|  105 |  106 |
|  106 |  107 |
|  107 | NULL |
+------+------+
10 rows in set (0.00 sec)select
cur+1 as start_range,
next-1 as end_range
from 
(
  select 
  a as cur,
  (select min(a) from x as x2
  where x2.a > x1.a)as next
  from x as x1
)as x3
where next - cur > 1
+-------------+-----------+
| start_range | end_range |
+-------------+-----------+
|           7 |        99 |
|         103 |       104 |
+-------------+-----------+
2 rows in set (0.01 sec)









