Sql 如何查找丢失的序列号?

Sql 如何查找丢失的序列号?,sql,oracle,Sql,Oracle,我有一个数据类型为NVARCHAR2的列。它的顺序值增加1,模式为D2017\S\S\S,从0000开始,继续向上。现在我有一直到D20179999的值,但从D20170001到D20179999我缺少10个值,我如何才能找到这些值 这就是你需要的。首先,您应该生成从D20170001到D20179999的范围。然后,您必须将它与顺序列右键联接,并找到null以获得缺少的范围 select * from your_table y right join (select 'D2017'||lpa

我有一个数据类型为NVARCHAR2的列。它的顺序值增加1,模式为D2017\S\S\S,从0000开始,继续向上。现在我有一直到D20179999的值,但从D20170001到D20179999我缺少10个值,我如何才能找到这些值

这就是你需要的。首先,您应该生成从D20170001到D20179999的范围。然后,您必须将它与顺序列右键联接,并找到null以获得缺少的范围

select * from your_table y
right join  
(select 'D2017'||lpad(to_char(level),4,'0') as c_range
      from dual connect by level < 10000) dt
on y.<range_column>=dt.c_range
where y.<range_column> is null

这就是你需要的。首先,您应该生成从D20170001到D20179999的范围。然后,您必须将它与顺序列右键联接,并找到null以获得缺少的范围

select * from your_table y
right join  
(select 'D2017'||lpad(to_char(level),4,'0') as c_range
      from dual connect by level < 10000) dt
on y.<range_column>=dt.c_range
where y.<range_column> is null

,您的问题不清楚。现在您有D20179999。但是您缺少D20170001到D20179999。只清楚地解释了信息,但这对oracle有用吗?-选择LEFT[MyField],8,COUNTLEFT[MyField],8从MyTable组中按LEFT[MyField],8有COUNTLEFT[MyField],8<10,您的问题不清楚。现在您有D20179999。但是您缺少D20170001到D20179999。清楚地解释了信息,但这在oracle上有效吗?-从MyTable group中按LEFT[MyField]选择LEFT[MyField],8,COUNTLEFT[MyField],8从MyTable group中选择8,8具有COUNTLEFT[MyField],8<10右连接的工作量大约是此操作所需工作量的两倍。更好的解决方案是像您所做的那样,从最小值到最大值生成所有值,然后在op_table的select op_列中添加where c_range not。但由于它可能适用于10000行,我几乎不认为这会有多大影响,但是的,应该尽可能遵循最佳性能方法。不管怎样,编辑的答案也适应这种方法。不要低估10k行到10k行,这是1亿个组合要考虑的!这是两个单独的查询还是一个一起查询?所以我已经有了数据,从'D20170000'到'D20179999',但是整个过程中有很多删除,如果一切都做得好的话,我应该有10000个值,我只有3050个值,我需要找到系统中不存在的7950个值。这是对问题的更好描述吗?不,这是相同的查询。您可以进行任何操作。Right join的工作量大约是此操作所需工作量的两倍。更好的解决方案是像您所做的那样,从最小值到最大值生成所有值,然后在op_table的select op_列中添加where c_range not。但由于它可能适用于10000行,我几乎不认为这会有多大影响,但是的,应该尽可能遵循最佳性能方法。不管怎样,编辑的答案也适应这种方法。不要低估10k行到10k行,这是1亿个组合要考虑的!这是两个单独的查询还是一个一起查询?所以我已经有了数据,从'D20170000'到'D20179999',但是整个过程中有很多删除,如果一切都做得好的话,我应该有10000个值,我只有3050个值,我需要找到系统中不存在的7950个值。这是对问题的更好描述吗?不,这是相同的查询。你可以做任何一件事。
with rt (e_range) as (
select 'D20179990' from dual union all
select 'D20179991' from dual union all
select 'D20179992' from dual union all
select 'D20179994' from dual union all
select 'D20179995' from dual union all
select 'D20179997' from dual union all
select 'D20179998' from dual union all
select 'D20179999' from dual)
select c_range from rt
right join (select 'D2017999'||to_char(level) as c_range from dual connect by level < 10) dt
on rt.e_range=dt.c_range
where rt.e_range is null
C_RANGE
D20179993
D20179996