Sql server 查找varchar变量中最后一个数值的序列

Sql server 查找varchar变量中最后一个数值的序列,sql-server,Sql Server,我在一个表中有一列,它的值递增,如: AAA0000001 AAA0000002 。。。等等 我想知道此列中存储的值是否按正确的顺序排列,或者中间是否缺少任何值,或者是否删除了任何值 如何实现这一点?假设模式始终为:AAA[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9],您可以通过理货表来实现 样本数据: CREATE TABLE Tbl(val VARCHAR(10)) INSERT INTO Tbl VALUES ('AAA0000001'), ('AAA

我在一个表中有一列,它的值递增,如:

AAA0000001
AAA0000002 
。。。等等

我想知道此列中存储的值是否按正确的顺序排列,或者中间是否缺少任何值,或者是否删除了任何值


如何实现这一点?

假设模式始终为:
AAA[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]
,您可以通过理货表来实现

样本数据:

CREATE TABLE Tbl(val VARCHAR(10))
INSERT INTO Tbl VALUES
('AAA0000001'), ('AAA0000002'), ('AAA0000004'), ('AAA0000011');

val
----------
AAA0000001
AAA0000002
AAA0000004
AAA0000011

结果

N                    val
-------------------- ----------
3                    AAA0000003
5                    AAA0000005
6                    AAA0000006
7                    AAA0000007
8                    AAA0000008
9                    AAA0000009
10                   AAA0000010

说明:

  • 第一个名为
    CTE
    CTE
    提取字符串的数字部分,并
    将其转换为
    INT
  • 随后的
    CTE
    s,从
    E1
    Tally(N)
    生成一个表,其中包含从
    1
    MAX(num)
    的顺序值-从第一个
    CTE
    返回的
    INT
  • 最后的
    SELECT
    只检查第一个
    CTE
    中不存在的
    num
  • 'AAA'+RIGHT('0000000'+CAST(N为VARCHAR(7)),7)
    转换
    N
    以使其遵循该模式

  • 这是一个缺口问题。您可以查看Dwain Camps的这篇文章,以了解更多有关的解决方案

    您可以像这样使用
    行号

    样本数据

    DECLARE @tab1 TABLE(id VARCHAR(20));
    
    insert into @tab1 VALUES('AAA0000001'),('AAA0000002'),('AAA0000003'),('AAA0000004'),('AAA0000006'),('AAA0000007'),('AAA0000010');
    
    查询

    ;WITH CTE as 
    (
    SELECT convert(int,STUFF(id,1,3,'')) id,convert(int,STUFF(id,1,3,'')) - ROW_NUMBER()OVER(ORDER BY convert(int,STUFF(id,1,3,''))) rn
    FROM @tab1
    ),CTE2 as 
    (
    SELECT ROW_NUMBER()OVER(ORDER BY rn) as rn, MIN(id) series_start,MAX(id) series_end
    FROM CTE
    GROUP BY rn
    )
    SELECT C2.series_end,C1.series_start
    FROM CTE2 C1
    INNER JOIN CTE2 C2 ON C1.rn = C2.rn + 1;
    

    解释

    • CTE的输出是id值之间的间隙差
    • CTE2的输出是连续数列的开始和结束
    • 最终输出给出系列中间隙的开始和结束
    输出

    series_end  series_start
    4   6
    7   10
    

    如果模式是固定的,那么就不需要复杂的查询。这项工作:

    DECLARE @t TABLE ( v VARCHAR(100) );
    
    INSERT  INTO @t
    VALUES  ( 'AAA0000001' ),
            ( 'AAA0000002' ),
            ( 'AAA0000007' ),
            ( 'AAA0000008' ),
            ( 'AAA0000010' ),
            ( 'AAA0000011' ),
            ( 'AAA0000012' );
    
    
    SELECT * FROM @t t1
    CROSS APPLY(SELECT TOP 1 v FROM @t t2 WHERE t2.v > t1.v ORDER BY v) ca
    WHERE RIGHT(t1.v, 7) <> RIGHT(ca.v, 7) - 1  
    

    在SQLServer2012中,可以使用和

    结果:

    previous_exists  next_exists  col1
    No               Yes          AAA0000001
    Yes              No           AAA0000002
    No               No           AAA0000004
    

    您期望的结果/预期的输出是什么?输出中应显示缺少的ID您是否有类似
    'aab000001'
    'aab000002'
    的记录?这些值是否具有一致的模式?10个字符,其中前3个是字母,后7个是数字。是的,前三个字符总是相同的,后7个是数字。没问题,很高兴我能帮上忙。
    v           v
    AAA0000002  AAA0000007
    AAA0000008  AAA0000010
    
    DECLARE @t table(col1 varchar(15))
    INSERT @t values('AAA0000001'),('AAA0000002'),('AAA0000004')
    
    SELECT 
      case when 
        stuff(lag(col1) over (order by col1), 1,3,'') + 1 
          = stuff(col1, 1,3,'') then 'Yes' else 'No' end previous_exists,
      case when
        stuff(lead(col1) over (order by col1), 1,3,'') - 1 
          = stuff(col1, 1,3,'') then 'Yes' else 'No' end next_exists,
      col1
    FROM @t
    
    previous_exists  next_exists  col1
    No               Yes          AAA0000001
    Yes              No           AAA0000002
    No               No           AAA0000004