我想识别字母数字序列中的缺失值。
该表的定义如下:
CREATE TABLE `seqtest` (
`ID` int(11) NOT NULL,
`PoleNo` text,
`Pre` char(1) DEFAULT NULL,
`Num` int(3) DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
数据如下所示,并且始终是一个字母(A-Z),后跟000至999之间的三个数字。
| PoleNo | Pre | Num |
|------------------------|
| A000 | A | 000 |
| A001 | A | 001 |
| A002 | A | 002 |
| A004 | A | 003 |
| **** | * | *** |
| A998 | A | 998 |
| A999 | A | 999 |
| B000 | B | 000 |
| B001 | B | 001 |
| B002 | B | 002 |
| **** | * | *** |
| B998 | B | 998 |
| B999 | B | 999 |
| C000 | C | 000 |
| C001 | C | 001 |
| C005 | C | 005 |
| C006 | C | 006 |
|------------------------|
我希望查询发现例如缺少C002,C003和C004,如下所示。
| Pre | start | stop |
| C | 2 | 4 |
|----------------------|
我使用以下内容:
SELECT l.Pre, l.Num + 1 as start, min(fr.Num) - 1 as stop
FROM seqtest as l
LEFT OUTER JOIN seqtest as r ON l.Num = r.Num - 1 AND l.Pre = r.Pre
LEFT OUTER JOIN seqtest as fr ON l.Num < fr.Num AND l.Pre = fr.Pre
WHERE r.Num is null AND l.Num < 999
GROUP BY l.Pre, l.Num, r.Num
基于this。
它给了我所缺少的范围,并且除了一种情况下效果很好之外……当“ Pre”从一个字母变为另一个字母时。
IE具有以下数据:
| PoleNo | Pre | Num |
|------------------------|
| B995 | B | 995 |
| B996 | B | 996 |
| B997 | B | 997 |
| C003 | C | 003 |
| C004 | C | 004 |
| C005 | C | 005 |
| C006 | C | 006 |
|------------------------|
Id希望能够返回此值:
| Pre | start | stop |
| B | 998 | 999 |
| C | 0 | 2 |
|----------------------|
这可能吗?我使用Pre
和Num
字段,它们只是将PoleNo
字段分解了...但是,如果有人发现仅使用PoleNo
字段就可以做到这一点,也可以。
答案 0 :(得分:0)
在MySQL 8+中,这要容易得多,因为您拥有lead()
。但是,您可以按照自己的意愿做:
select st.pre,
(st.num + 1) as start,
(st.next_num - 1) as stop
from (select st.*,
(select st2.num
from seqtest st2
where st2.pre = st.pre and
st2.num > st.num
order by st2.num asc
limit 1
) as next_num
from seqtest st
) st
where next_num <> num + 1;
编辑:
这也将获得范围的开头和结尾:
select st.pre,
(st.num + 1) as start,
(st.next_num - 1) as stop
from (select st.pre, num,
coalesce( (select st2.num
from seqtest st2
where st2.pre = st.pre and
st2.num > st.num
order by st2.num asc
limit 1), 1000
) as next_num
from seqtest st
union
select st.pre, 0 as num, min(st.num) as next_num
from seqtest st
group by st.pre
) st
where next_num <> num + 1
order by pre, start;
Here是db <>小提琴。