下一个可用值 - postgresql

时间:2016-02-12 13:13:48

标签: sql postgresql

我的客户端号码是三个字符。 '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

提前感谢任何线索。

3 个答案:

答案 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>