Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.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/7/sql-server/23.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
Sql 获取每个部分缺少的编号_Sql_Sql Server_Tsql - Fatal编程技术网

Sql 获取每个部分缺少的编号

Sql 获取每个部分缺少的编号,sql,sql-server,tsql,Sql,Sql Server,Tsql,我想从每个部分的列表中获取缺少的协议编号 我有我的名单 ProtocolNumber Section -------------------------------- 14A1000014 | A1 14A1000015 | A1 14A1000018 | A1 14A1000019 | A1 14A2000014 | A2 14A2000015 | A2 14A2000

我想从每个部分的列表中获取缺少的协议编号 我有我的名单

    ProtocolNumber  Section
--------------------------------
    14A1000014  |     A1
    14A1000015  |     A1
    14A1000018  |     A1
    14A1000019  |     A1
    14A2000014  |     A2
    14A2000015  |     A2
    14A2000019  |     A2
我试试这个

SELECT  lb1.ProtocolNumber, lb1.Section  FROM #tmp lb1 
        WHERE not exists ( SELECT * FROM #tmp lb2
                       WHERE lb2.ProtocolNumber = lb1.ProtocolNumber + 1  and lb2.Section = lb1.Section)
输出应该是这样的

   ProtocolNumber   Section
--------------------------------
    14A1000016  |     A1
    14A1000017  |     A1
    14A2000016  |     A2
    14A2000017  |     A2
    14A2000018  |     A2

它必须是单线选择状态吗

编写一个存储过程或表值函数,使用游标在表中迭代并创建丢失的记录,然后函数返回,怎么样


实施还需要检查每个给定部分的最大协议号,以便您仅创建范围内的记录,假设您正在尝试生成该部分当前存在的最小和最大范围之间缺少的协议号列表,我建议如下:

/*Sample Data*/
CREATE TABLE #tmp (ProtocolNumber VARCHAR(20), Section VARCHAR(2))
INSERT INTO #tmp (ProtocolNumber, Section) SELECT'14A1000014',      'A1' 
INSERT INTO #tmp (ProtocolNumber, Section) SELECT'14A1000015',      'A1'
INSERT INTO #tmp (ProtocolNumber, Section) SELECT'14A1000018',      'A1'
INSERT INTO #tmp (ProtocolNumber, Section) SELECT'14A1000019',      'A1'
INSERT INTO #tmp (ProtocolNumber, Section) SELECT'14A2000014',      'A2'
INSERT INTO #tmp (ProtocolNumber, Section) SELECT'14A2000015',      'A2'
INSERT INTO #tmp (ProtocolNumber, Section) SELECT'14A2000019',      'A2'

/*CTEs to generate numbers list: 1 through 1,000,000*/
;WITH 
    E1(N) AS (SELECT 1 FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) s(N)), 
    E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows 
    E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max 
    E5(N) AS (SELECT 1 FROM E4 a, E2 b), --1,000,000 rows max 
    cteTally(N) AS ( SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E5 ),
/*CTE to identify ranges of current numbers for each Section*/
    Ranges AS 
      (
        SELECT 
            Section, 
            MIN(CAST(SUBSTRING(ProtocolNumber, 5,6) AS INT)) MinNumber, 
            MAX(CAST(SUBSTRING(ProtocolNumber, 5,6) AS INT)) MaxNumber
        FROM 
            #tmp 
        GROUP BY Section 
      ),
/*CTE to generate full list of available protocols for each Section*/
    ProtocolList AS 
      (
        SELECT DISTINCT 
            Section,
            '14' + Section + RIGHT('00000' + CAST(N AS VARCHAR(6)),6) AS ProtocolNumber
        FROM Ranges 
         INNER JOIN 
        cteTally ON 
            cteTally.N >= Ranges.MinNumber AND 
            cteTally.N <= Ranges.MaxNumber

      )

/*Final SELECT - protocols in the master list that do not exist for those sections in the temp table*/

SELECT l.ProtocolNumber, l.Section
FROM 
    ProtocolList l
     LEFT JOIN 
    #tmp t ON 
        l.ProtocolNumber = t.ProtocolNumber
WHERE t.ProtocolNumber IS NULL 
ORDER BY 
    l.Section, 
    l.ProtocolNumber

DROP TABLE #tmp 

缺失协议列表

 DECLARE @P INT=(SELECT  COUNT(DISTINCT SECTION) FROM PROTOCOL) --NUMBER OF SECTION
DECLARE @w varchar(10)='A1'   --HOLD TYPE OF SECTION
WHILE @P>0
BEGIN
DECLARE @q table(numx int)  --HOLD MAX TO MIN ProtocolNumber
declare @i table(num int)   --HOLD EXISTS 'ProtocolNumber'
INSERT INTO @i
select  convert(int,right( ProtocolNumber,2)) FROM protocol  WHERE Section=@w
DECLARE @x int=(select max(convert(int,right( ProtocolNumber,2))) FROM protocol WHERE Section=@w)
DECLARE @y int=(select min(convert(int,right( ProtocolNumber,2))) FROM protocol WHERE Section=@w)
 WHILE @y <= @x  
begin
INSERT INTO @q (numx)
VALUES(@y)
SET @y= @y + 1
END
SELECT ('14'+@w+'0000'+ convert(varchar(10),numx)) AS ProtocolNumber,@W AS Section
FROM  @Q
 where  numx NOT IN (select  * FROM @i)
  SET @P=@P-1
 SET @W='A2'
 DELETE FROM @Q
 DELETE  FROM @I
 END

你能提供一个预期的输出吗?什么定义了一个缺失的数字?如果你想检查可能值范围内的所有值,是什么定义了这个范围?我想我的代码是wrong@New_World,您能否提供有关ProtocolNumber字段的一些详细信息?它是否总是等于14+节+6位数?什么定义了6位数字的开始/结束范围?哪些6位数字有效?因为他们有一百万。字面意思。你能给我举个例子吗?请用你的表名替换“协议”。我想你可以在比较Ctetaly和Ranges min/max时去掉“=”。你也可以排除行,除非max min>2。@Beth,我相信你是对的!我经常遇到这样的问题,试图得到所有可能的和任何匹配存在的,但由于OP要求只看到缺失,=符号是多余的。尽管如此,为了简单起见,以及万一需求发生变化以覆盖该场景,我将保持原样。不过,谢谢你指出这一点!