Sql server T-SQL-接收两个数字之间的间隙

Sql server T-SQL-接收两个数字之间的间隙,sql-server,tsql,Sql Server,Tsql,我正在使用SQL Server 2012 我收到一个“最大数字”f.e.201900005,这告诉我范围从201900000开始(这是给定的)。现在我想接收在此范围内丢失的数字 我已经研究了几个关于这方面的问题,但我似乎无法让它起作用。使用中间或光标对照表本身检查表 Max Number = 201900005, Min Number = 201900000 当前流程使用一个“帮助”表,该表基本上包含201900000和201900005之间的所有数字(实际情况下更多),并将这些数字与测试表中

我正在使用SQL Server 2012

我收到一个“最大数字”f.e.201900005,这告诉我范围从201900000开始(这是给定的)。现在我想接收在此范围内丢失的数字

我已经研究了几个关于这方面的问题,但我似乎无法让它起作用。使用中间或光标对照表本身检查表

Max Number = 201900005, Min Number = 201900000
当前流程使用一个“帮助”表,该表基本上包含201900000和201900005之间的所有数字(实际情况下更多),并将这些数字与测试表中的ONCE进行比较


如果您有任何建议,我将不胜感激。

就我个人而言,我将使用计数创建一个包含所有可能数字的列表,然后
将该列表左键连接到您的表中,并返回不匹配的行:

CREATE TABLE dbo.Test_Table (Test_Number int);
INSERT INTO dbo.Test_Table (Test_Number)
VALUES(201900001),(201900003),(201900004);
GO

DECLARE @Start int = 201900000,
        @End int = 201900005;

WITH N AS(
    SELECT N
    FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N(N)),
Tally AS(
    SELECT TOP (@End - @Start +1) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1 + @Start AS I
    FROM N N1, N N2, N N3) --1000 rows, if you need more, just add more
SELECT T.I
FROM Tally T
     LEFT JOIN dbo.Test_Table TT ON T.I = TT.Test_Number
WHERE TT.Test_Number IS NULL;

GO

DROP TABLE dbo.Test_Table;

这只是另一个使用特殊理货表和联合全票的选项

示例

Declare @R1 int = 201900000
Declare @R2 int = 201900005

Select Missing = N
 From  (
        Select Top (@R2-@R1+1) N=@R1-1+Row_Number() Over (Order By (Select NULL)) From  master..spt_values n1, master..spt_values n2 
        Union All
        Select test_number from test_table Where test_number between @R1 and @R2
       ) A
 Group By N
 Having count(*)=1
返回

Missing
201900000
201900002
201900005

这正是我想要的。你能向我解释一下你在“WITH”-声明中做了什么吗?“我真的不明白它是如何工作的……我正在用CTE来创建一个计数,”Frozzo说。第一个CTE(
N
)只创建10行,值为
NULL
。然后在第二个CTE(
Tally
)中,我创建了
N
中行的笛卡尔乘积。在这种情况下,由于
N
交叉连接了3次,即10*10*10行=1000行(我猜您可能需要5行以上)。我使用
TOP
限制行数,以提高性能,并使用
行数
创建递增的数字(由于
TOP
的原因,从
@Start
开始,到
@End
结束)。最后的陈述应该是不言自明的。如果我没有超过“Max number”的数字(应该添加,这是用户为确定最大范围而清除的属性),则此解决方案有效。但是,如果我的表中有一个201900009,则它也将是displayed@Frozzo很公平,如果我知道这个用例,我会简单地在R1和R2之间添加TEST_编号,我倾向于使用我的Select Top。。。用于临时理货表,而不是CTE。
Declare @R1 int = 201900000
Declare @R2 int = 201900005

Select Missing = N
 From  (
        Select Top (@R2-@R1+1) N=@R1-1+Row_Number() Over (Order By (Select NULL)) From  master..spt_values n1, master..spt_values n2 
        Union All
        Select test_number from test_table Where test_number between @R1 and @R2
       ) A
 Group By N
 Having count(*)=1
Missing
201900000
201900002
201900005