版权声明:如若转载,请联系作者。 https://blog.csdn.net/liu16659/article/details/82813151
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)