Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
下一个可用值-postgresql_Sql_Postgresql - Fatal编程技术网

下一个可用值-postgresql

下一个可用值-postgresql,sql,postgresql,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

我有三个字符的客户号码。”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:

提前感谢您提供的任何线索。

您可以使用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;

@戈登林诺夫的想法是正确的,但我不确定能否实现

下面是我的查询版本:

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>

它将查找“009”,而不是第一个可用号码“004”。第二个查询将提供可用的“002”@西伯特。查询工作正常。您的SQL FIDLE错误:。我不知道你的CTE来自哪里。如果没有CTE,AFAIK:错误:关系号不存在?@sibert。我刚刚使用了你选择的命名约定。我不知道这张桌子还有其他名字。谢谢!简单干净。它像预期的那样工作。
select '000' union all <your data>