Mysql实战之求出缺失范围

版权声明:如若转载,请联系作者。 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)

猜你喜欢

转载自blog.csdn.net/liu16659/article/details/82813151