我的客户端号码是三个字符。 '001'到'999'。有时会出现可以重复使用的空白。我想填补这个空白。所以我正在寻找找到第一个可用差距的方法。
CREATE TABLE co
( co_clno varchar(3));
INSERT INTO co
VALUES
('001'),
('002'),
('003'),
('005'),
('006'),
('007'),
('008');
这里的可用差距是'004'
我试图首先创建一个没有成功的可用号码列表:
WITH numbers AS
(SELECT to_char(generate_series(1,9),'000') num)
SELECT num FROM numbers
WHERE num NOT IN(SELECT co_clno FROM co)
最终代码应该是:
WITH numbers AS
(SELECT to_char(generate_series(1,9),'000') num)
SELECT min(num) FROM numbers
WHERE num NOT IN(SELECT co_clno FROM co)
SQLFiddle:http://sqlfiddle.com/#!15/1e48d/1
提前感谢任何线索。
答案 0 :(得分:2)
select substring(to_char(n,'000') from 2) as num
from generate_series(1,9) gs(n)
except
select co_clno
from co
order by 1
limit 1
答案 1 :(得分:1)
您可以使用lead()
查找差距的开始位置:
select n.*
from (select n.*, lead(co_clno) over (order by co_clno) as next_num
from co n
) n
where next_num is null or
n. co_clno::int <> (next_num::int) - 1
order by co_clno
limit 1;
您可以使用以下内容获取下一个值:
select to_char((n. co_clno::int) + 1, '000')
from (select n.*, lead(co_clno) over (order by co_clno) as next_num
from co n
) n
where next_num is null or
n. co_clno::int <> next_num::int
order by co_clno
limit 1;
唯一的问题是如果丢失它将不会获得第一个值。嗯。 。
select (case when first_num <> '001' then '001'
else min(to_char((n. co_clno::int) + 1, '000'))
end)
from (select n.*, lead(co_clno) over (order by co_clno) as next_num,
min(co_clno) over () as first_num
from co n
) n
where next_num is null or
n. co_clno::int <> (next_num::int) - 1
group by first_num;
答案 2 :(得分:0)
@ GordonLinoff的想法是正确的,但我不确定实现。
所以这是我的查询版本:
with
t(n) as (
values
('001'),
('002'),
('005'),
('003'),
('006'),
('009'),
('010'),
('012')),
t1 as (
select
n,
lag(n, -1) over (order by n)::int - n::int - 1 as cnt
from t)
select
to_char(generate_series(n::int+1, n::int+cnt), '000') as gap
from
t1
where
cnt > 0;
结果是:
gap
------
004
007
008
011
(4 rows)
要解决缺少第一个值的问题,请使用
select '000' union all <your data>